@unifiedcommerce/core 0.0.1
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/adapters/console-email.d.ts +23 -0
- package/dist/adapters/console-email.d.ts.map +1 -0
- package/dist/adapters/console-email.js +38 -0
- package/dist/auth/access.d.ts +101 -0
- package/dist/auth/access.d.ts.map +1 -0
- package/dist/auth/access.js +128 -0
- package/dist/auth/auth-schema.d.ts +1383 -0
- package/dist/auth/auth-schema.d.ts.map +1 -0
- package/dist/auth/auth-schema.js +117 -0
- package/dist/auth/middleware.d.ts +5 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +91 -0
- package/dist/auth/org.d.ts +22 -0
- package/dist/auth/org.d.ts.map +1 -0
- package/dist/auth/org.js +36 -0
- package/dist/auth/permissions.d.ts +4 -0
- package/dist/auth/permissions.d.ts.map +1 -0
- package/dist/auth/permissions.js +24 -0
- package/dist/auth/pos.d.ts +3 -0
- package/dist/auth/pos.d.ts.map +1 -0
- package/dist/auth/pos.js +62 -0
- package/dist/auth/setup.d.ts +31 -0
- package/dist/auth/setup.d.ts.map +1 -0
- package/dist/auth/setup.js +106 -0
- package/dist/auth/system-actor.d.ts +7 -0
- package/dist/auth/system-actor.d.ts.map +1 -0
- package/dist/auth/system-actor.js +17 -0
- package/dist/auth/types.d.ts +11 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +1 -0
- package/dist/config/defaults.d.ts +3 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +80 -0
- package/dist/config/define-config.d.ts +9 -0
- package/dist/config/define-config.d.ts.map +1 -0
- package/dist/config/define-config.js +44 -0
- package/dist/config/types.d.ts +299 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +1 -0
- package/dist/generated/plugin-manifest.d.ts +48 -0
- package/dist/generated/plugin-manifest.d.ts.map +1 -0
- package/dist/generated/plugin-manifest.js +20 -0
- package/dist/hooks/checkout-completion.d.ts +58 -0
- package/dist/hooks/checkout-completion.d.ts.map +1 -0
- package/dist/hooks/checkout-completion.js +137 -0
- package/dist/hooks/checkout.d.ts +99 -0
- package/dist/hooks/checkout.d.ts.map +1 -0
- package/dist/hooks/checkout.js +317 -0
- package/dist/hooks/order-emails.d.ts +16 -0
- package/dist/hooks/order-emails.d.ts.map +1 -0
- package/dist/hooks/order-emails.js +44 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13381 -0
- package/dist/index.js.map +156 -0
- package/dist/interfaces/graphql/index.d.ts +4 -0
- package/dist/interfaces/graphql/index.d.ts.map +1 -0
- package/dist/interfaces/graphql/index.js +415 -0
- package/dist/interfaces/mcp/agent-prompt.d.ts +16 -0
- package/dist/interfaces/mcp/agent-prompt.d.ts.map +1 -0
- package/dist/interfaces/mcp/agent-prompt.js +172 -0
- package/dist/interfaces/mcp/context-enrichment.d.ts +39 -0
- package/dist/interfaces/mcp/context-enrichment.d.ts.map +1 -0
- package/dist/interfaces/mcp/context-enrichment.js +119 -0
- package/dist/interfaces/mcp/server.d.ts +7 -0
- package/dist/interfaces/mcp/server.d.ts.map +1 -0
- package/dist/interfaces/mcp/server.js +515 -0
- package/dist/interfaces/mcp/transport.d.ts +5 -0
- package/dist/interfaces/mcp/transport.d.ts.map +1 -0
- package/dist/interfaces/mcp/transport.js +52 -0
- package/dist/interfaces/rest/customer-portal.d.ts +5 -0
- package/dist/interfaces/rest/customer-portal.d.ts.map +1 -0
- package/dist/interfaces/rest/customer-portal.js +206 -0
- package/dist/interfaces/rest/index.d.ts +5 -0
- package/dist/interfaces/rest/index.d.ts.map +1 -0
- package/dist/interfaces/rest/index.js +68 -0
- package/dist/interfaces/rest/router.d.ts +164 -0
- package/dist/interfaces/rest/router.d.ts.map +1 -0
- package/dist/interfaces/rest/router.js +259 -0
- package/dist/interfaces/rest/routes/admin-jobs.d.ts +5 -0
- package/dist/interfaces/rest/routes/admin-jobs.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/admin-jobs.js +48 -0
- package/dist/interfaces/rest/routes/audit.d.ts +5 -0
- package/dist/interfaces/rest/routes/audit.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/audit.js +43 -0
- package/dist/interfaces/rest/routes/carts.d.ts +5 -0
- package/dist/interfaces/rest/routes/carts.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/carts.js +55 -0
- package/dist/interfaces/rest/routes/catalog.d.ts +5 -0
- package/dist/interfaces/rest/routes/catalog.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/catalog.js +256 -0
- package/dist/interfaces/rest/routes/checkout.d.ts +5 -0
- package/dist/interfaces/rest/routes/checkout.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/checkout.js +216 -0
- package/dist/interfaces/rest/routes/inventory.d.ts +5 -0
- package/dist/interfaces/rest/routes/inventory.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/inventory.js +59 -0
- package/dist/interfaces/rest/routes/media.d.ts +5 -0
- package/dist/interfaces/rest/routes/media.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/media.js +65 -0
- package/dist/interfaces/rest/routes/orders.d.ts +5 -0
- package/dist/interfaces/rest/routes/orders.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/orders.js +64 -0
- package/dist/interfaces/rest/routes/payments.d.ts +5 -0
- package/dist/interfaces/rest/routes/payments.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/payments.js +45 -0
- package/dist/interfaces/rest/routes/pricing.d.ts +5 -0
- package/dist/interfaces/rest/routes/pricing.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/pricing.js +48 -0
- package/dist/interfaces/rest/routes/promotions.d.ts +5 -0
- package/dist/interfaces/rest/routes/promotions.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/promotions.js +75 -0
- package/dist/interfaces/rest/routes/search.d.ts +5 -0
- package/dist/interfaces/rest/routes/search.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/search.js +60 -0
- package/dist/interfaces/rest/routes/webhooks.d.ts +5 -0
- package/dist/interfaces/rest/routes/webhooks.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/webhooks.js +39 -0
- package/dist/interfaces/rest/schemas/admin-jobs.d.ts +327 -0
- package/dist/interfaces/rest/schemas/admin-jobs.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/admin-jobs.js +37 -0
- package/dist/interfaces/rest/schemas/audit.d.ts +59 -0
- package/dist/interfaces/rest/schemas/audit.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/audit.js +43 -0
- package/dist/interfaces/rest/schemas/carts.d.ts +1446 -0
- package/dist/interfaces/rest/schemas/carts.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/carts.js +109 -0
- package/dist/interfaces/rest/schemas/catalog.d.ts +5416 -0
- package/dist/interfaces/rest/schemas/catalog.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/catalog.js +397 -0
- package/dist/interfaces/rest/schemas/checkout.d.ts +160 -0
- package/dist/interfaces/rest/schemas/checkout.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/checkout.js +60 -0
- package/dist/interfaces/rest/schemas/customer-portal.d.ts +2197 -0
- package/dist/interfaces/rest/schemas/customer-portal.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/customer-portal.js +177 -0
- package/dist/interfaces/rest/schemas/inventory.d.ts +469 -0
- package/dist/interfaces/rest/schemas/inventory.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/inventory.js +128 -0
- package/dist/interfaces/rest/schemas/media.d.ts +303 -0
- package/dist/interfaces/rest/schemas/media.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/media.js +69 -0
- package/dist/interfaces/rest/schemas/orders.d.ts +1782 -0
- package/dist/interfaces/rest/schemas/orders.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/orders.js +93 -0
- package/dist/interfaces/rest/schemas/pricing.d.ts +256 -0
- package/dist/interfaces/rest/schemas/pricing.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/pricing.js +72 -0
- package/dist/interfaces/rest/schemas/promotions.d.ts +363 -0
- package/dist/interfaces/rest/schemas/promotions.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/promotions.js +98 -0
- package/dist/interfaces/rest/schemas/responses.d.ts +4062 -0
- package/dist/interfaces/rest/schemas/responses.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/responses.js +63 -0
- package/dist/interfaces/rest/schemas/search.d.ts +245 -0
- package/dist/interfaces/rest/schemas/search.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/search.js +55 -0
- package/dist/interfaces/rest/schemas/shared.d.ts +95 -0
- package/dist/interfaces/rest/schemas/shared.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/shared.js +51 -0
- package/dist/interfaces/rest/schemas/webhooks.d.ts +221 -0
- package/dist/interfaces/rest/schemas/webhooks.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/webhooks.js +62 -0
- package/dist/interfaces/rest/utils.d.ts +45 -0
- package/dist/interfaces/rest/utils.d.ts.map +1 -0
- package/dist/interfaces/rest/utils.js +71 -0
- package/dist/interfaces/rest/webhook-router.d.ts +41 -0
- package/dist/interfaces/rest/webhook-router.d.ts.map +1 -0
- package/dist/interfaces/rest/webhook-router.js +36 -0
- package/dist/kernel/compensation/executor.d.ts +21 -0
- package/dist/kernel/compensation/executor.d.ts.map +1 -0
- package/dist/kernel/compensation/executor.js +36 -0
- package/dist/kernel/compensation/types.d.ts +25 -0
- package/dist/kernel/compensation/types.d.ts.map +1 -0
- package/dist/kernel/compensation/types.js +1 -0
- package/dist/kernel/database/adapter.d.ts +10 -0
- package/dist/kernel/database/adapter.d.ts.map +1 -0
- package/dist/kernel/database/adapter.js +3 -0
- package/dist/kernel/database/drizzle-db.d.ts +49 -0
- package/dist/kernel/database/drizzle-db.d.ts.map +1 -0
- package/dist/kernel/database/drizzle-db.js +20 -0
- package/dist/kernel/database/migrate.d.ts +38 -0
- package/dist/kernel/database/migrate.d.ts.map +1 -0
- package/dist/kernel/database/migrate.js +61 -0
- package/dist/kernel/database/plugin-types.d.ts +32 -0
- package/dist/kernel/database/plugin-types.d.ts.map +1 -0
- package/dist/kernel/database/plugin-types.js +10 -0
- package/dist/kernel/database/schema.d.ts +24 -0
- package/dist/kernel/database/schema.d.ts.map +1 -0
- package/dist/kernel/database/schema.js +36 -0
- package/dist/kernel/database/scoped-db.d.ts +20 -0
- package/dist/kernel/database/scoped-db.d.ts.map +1 -0
- package/dist/kernel/database/scoped-db.js +62 -0
- package/dist/kernel/database/tx-context.d.ts +15 -0
- package/dist/kernel/database/tx-context.d.ts.map +1 -0
- package/dist/kernel/database/tx-context.js +19 -0
- package/dist/kernel/error-mapper.d.ts +3 -0
- package/dist/kernel/error-mapper.d.ts.map +1 -0
- package/dist/kernel/error-mapper.js +12 -0
- package/dist/kernel/errors.d.ts +38 -0
- package/dist/kernel/errors.d.ts.map +1 -0
- package/dist/kernel/errors.js +69 -0
- package/dist/kernel/factory/in-memory-repository-factory.d.ts +20 -0
- package/dist/kernel/factory/in-memory-repository-factory.d.ts.map +1 -0
- package/dist/kernel/factory/in-memory-repository-factory.js +83 -0
- package/dist/kernel/factory/repository-factory.d.ts +71 -0
- package/dist/kernel/factory/repository-factory.d.ts.map +1 -0
- package/dist/kernel/factory/repository-factory.js +136 -0
- package/dist/kernel/hooks/create-context.d.ts +25 -0
- package/dist/kernel/hooks/create-context.d.ts.map +1 -0
- package/dist/kernel/hooks/create-context.js +22 -0
- package/dist/kernel/hooks/executor.d.ts +12 -0
- package/dist/kernel/hooks/executor.d.ts.map +1 -0
- package/dist/kernel/hooks/executor.js +50 -0
- package/dist/kernel/hooks/registry.d.ts +28 -0
- package/dist/kernel/hooks/registry.d.ts.map +1 -0
- package/dist/kernel/hooks/registry.js +58 -0
- package/dist/kernel/hooks/types.d.ts +37 -0
- package/dist/kernel/hooks/types.d.ts.map +1 -0
- package/dist/kernel/hooks/types.js +1 -0
- package/dist/kernel/http-error.d.ts +30 -0
- package/dist/kernel/http-error.d.ts.map +1 -0
- package/dist/kernel/http-error.js +35 -0
- package/dist/kernel/jobs/adapter.d.ts +25 -0
- package/dist/kernel/jobs/adapter.d.ts.map +1 -0
- package/dist/kernel/jobs/adapter.js +9 -0
- package/dist/kernel/jobs/drizzle-adapter.d.ts +15 -0
- package/dist/kernel/jobs/drizzle-adapter.d.ts.map +1 -0
- package/dist/kernel/jobs/drizzle-adapter.js +42 -0
- package/dist/kernel/jobs/runner.d.ts +24 -0
- package/dist/kernel/jobs/runner.d.ts.map +1 -0
- package/dist/kernel/jobs/runner.js +114 -0
- package/dist/kernel/jobs/schema.d.ts +280 -0
- package/dist/kernel/jobs/schema.d.ts.map +1 -0
- package/dist/kernel/jobs/schema.js +37 -0
- package/dist/kernel/jobs/types.d.ts +30 -0
- package/dist/kernel/jobs/types.d.ts.map +1 -0
- package/dist/kernel/jobs/types.js +1 -0
- package/dist/kernel/local-api.d.ts +103 -0
- package/dist/kernel/local-api.d.ts.map +1 -0
- package/dist/kernel/local-api.js +87 -0
- package/dist/kernel/plugin/capability-registry.d.ts +9 -0
- package/dist/kernel/plugin/capability-registry.d.ts.map +1 -0
- package/dist/kernel/plugin/capability-registry.js +28 -0
- package/dist/kernel/plugin/dependency-graph.d.ts +6 -0
- package/dist/kernel/plugin/dependency-graph.d.ts.map +1 -0
- package/dist/kernel/plugin/dependency-graph.js +55 -0
- package/dist/kernel/plugin/manifest.d.ts +90 -0
- package/dist/kernel/plugin/manifest.d.ts.map +1 -0
- package/dist/kernel/plugin/manifest.js +140 -0
- package/dist/kernel/query/executor.d.ts +21 -0
- package/dist/kernel/query/executor.d.ts.map +1 -0
- package/dist/kernel/query/executor.js +128 -0
- package/dist/kernel/query/registry.d.ts +33 -0
- package/dist/kernel/query/registry.d.ts.map +1 -0
- package/dist/kernel/query/registry.js +20 -0
- package/dist/kernel/result.d.ts +36 -0
- package/dist/kernel/result.d.ts.map +1 -0
- package/dist/kernel/result.js +16 -0
- package/dist/kernel/schema/extra-columns.d.ts +23 -0
- package/dist/kernel/schema/extra-columns.d.ts.map +1 -0
- package/dist/kernel/schema/extra-columns.js +10 -0
- package/dist/kernel/service-registry.d.ts +109 -0
- package/dist/kernel/service-registry.d.ts.map +1 -0
- package/dist/kernel/service-registry.js +26 -0
- package/dist/kernel/service-timing.d.ts +25 -0
- package/dist/kernel/service-timing.d.ts.map +1 -0
- package/dist/kernel/service-timing.js +62 -0
- package/dist/kernel/state-machine/machine.d.ts +24 -0
- package/dist/kernel/state-machine/machine.d.ts.map +1 -0
- package/dist/kernel/state-machine/machine.js +70 -0
- package/dist/modules/analytics/cubes.d.ts +19 -0
- package/dist/modules/analytics/cubes.d.ts.map +1 -0
- package/dist/modules/analytics/cubes.js +187 -0
- package/dist/modules/analytics/drizzle-adapter.d.ts +13 -0
- package/dist/modules/analytics/drizzle-adapter.d.ts.map +1 -0
- package/dist/modules/analytics/drizzle-adapter.js +358 -0
- package/dist/modules/analytics/hooks.d.ts +13 -0
- package/dist/modules/analytics/hooks.d.ts.map +1 -0
- package/dist/modules/analytics/hooks.js +12 -0
- package/dist/modules/analytics/models.d.ts +14 -0
- package/dist/modules/analytics/models.d.ts.map +1 -0
- package/dist/modules/analytics/models.js +118 -0
- package/dist/modules/analytics/repository/index.d.ts +5 -0
- package/dist/modules/analytics/repository/index.d.ts.map +1 -0
- package/dist/modules/analytics/repository/index.js +1 -0
- package/dist/modules/analytics/service.d.ts +45 -0
- package/dist/modules/analytics/service.d.ts.map +1 -0
- package/dist/modules/analytics/service.js +196 -0
- package/dist/modules/analytics/types.d.ts +119 -0
- package/dist/modules/analytics/types.d.ts.map +1 -0
- package/dist/modules/analytics/types.js +25 -0
- package/dist/modules/audit/hooks.d.ts +7 -0
- package/dist/modules/audit/hooks.d.ts.map +1 -0
- package/dist/modules/audit/hooks.js +67 -0
- package/dist/modules/audit/schema.d.ts +178 -0
- package/dist/modules/audit/schema.d.ts.map +1 -0
- package/dist/modules/audit/schema.js +21 -0
- package/dist/modules/audit/service.d.ts +38 -0
- package/dist/modules/audit/service.d.ts.map +1 -0
- package/dist/modules/audit/service.js +109 -0
- package/dist/modules/cart/access.d.ts +11 -0
- package/dist/modules/cart/access.d.ts.map +1 -0
- package/dist/modules/cart/access.js +18 -0
- package/dist/modules/cart/matcher.d.ts +20 -0
- package/dist/modules/cart/matcher.d.ts.map +1 -0
- package/dist/modules/cart/matcher.js +2 -0
- package/dist/modules/cart/repository/in-memory.d.ts +30 -0
- package/dist/modules/cart/repository/in-memory.d.ts.map +1 -0
- package/dist/modules/cart/repository/in-memory.js +159 -0
- package/dist/modules/cart/repository/index.d.ts +45 -0
- package/dist/modules/cart/repository/index.d.ts.map +1 -0
- package/dist/modules/cart/repository/index.js +158 -0
- package/dist/modules/cart/schema.d.ts +359 -0
- package/dist/modules/cart/schema.d.ts.map +1 -0
- package/dist/modules/cart/schema.js +40 -0
- package/dist/modules/cart/schemas.d.ts +29 -0
- package/dist/modules/cart/schemas.d.ts.map +1 -0
- package/dist/modules/cart/schemas.js +14 -0
- package/dist/modules/cart/service.d.ts +63 -0
- package/dist/modules/cart/service.d.ts.map +1 -0
- package/dist/modules/cart/service.js +339 -0
- package/dist/modules/catalog/repository/in-memory.d.ts +82 -0
- package/dist/modules/catalog/repository/in-memory.d.ts.map +1 -0
- package/dist/modules/catalog/repository/in-memory.js +444 -0
- package/dist/modules/catalog/repository/index.d.ts +106 -0
- package/dist/modules/catalog/repository/index.d.ts.map +1 -0
- package/dist/modules/catalog/repository/index.js +455 -0
- package/dist/modules/catalog/schema.d.ts +1193 -0
- package/dist/modules/catalog/schema.d.ts.map +1 -0
- package/dist/modules/catalog/schema.js +149 -0
- package/dist/modules/catalog/schemas.d.ts +81 -0
- package/dist/modules/catalog/schemas.d.ts.map +1 -0
- package/dist/modules/catalog/schemas.js +62 -0
- package/dist/modules/catalog/service.d.ts +160 -0
- package/dist/modules/catalog/service.d.ts.map +1 -0
- package/dist/modules/catalog/service.js +759 -0
- package/dist/modules/customers/repository/in-memory.d.ts +37 -0
- package/dist/modules/customers/repository/in-memory.d.ts.map +1 -0
- package/dist/modules/customers/repository/in-memory.js +278 -0
- package/dist/modules/customers/repository/index.d.ts +47 -0
- package/dist/modules/customers/repository/index.d.ts.map +1 -0
- package/dist/modules/customers/repository/index.js +206 -0
- package/dist/modules/customers/schema.d.ts +560 -0
- package/dist/modules/customers/schema.d.ts.map +1 -0
- package/dist/modules/customers/schema.js +60 -0
- package/dist/modules/customers/service.d.ts +25 -0
- package/dist/modules/customers/service.d.ts.map +1 -0
- package/dist/modules/customers/service.js +91 -0
- package/dist/modules/fulfillment/repository/in-memory.d.ts +53 -0
- package/dist/modules/fulfillment/repository/in-memory.d.ts.map +1 -0
- package/dist/modules/fulfillment/repository/in-memory.js +327 -0
- package/dist/modules/fulfillment/repository/index.d.ts +63 -0
- package/dist/modules/fulfillment/repository/index.d.ts.map +1 -0
- package/dist/modules/fulfillment/repository/index.js +268 -0
- package/dist/modules/fulfillment/schema.d.ts +655 -0
- package/dist/modules/fulfillment/schema.d.ts.map +1 -0
- package/dist/modules/fulfillment/schema.js +83 -0
- package/dist/modules/fulfillment/service.d.ts +58 -0
- package/dist/modules/fulfillment/service.d.ts.map +1 -0
- package/dist/modules/fulfillment/service.js +338 -0
- package/dist/modules/fulfillment/types.d.ts +44 -0
- package/dist/modules/fulfillment/types.d.ts.map +1 -0
- package/dist/modules/fulfillment/types.js +1 -0
- package/dist/modules/inventory/repository/in-memory.d.ts +51 -0
- package/dist/modules/inventory/repository/in-memory.d.ts.map +1 -0
- package/dist/modules/inventory/repository/in-memory.js +281 -0
- package/dist/modules/inventory/repository/index.d.ts +81 -0
- package/dist/modules/inventory/repository/index.d.ts.map +1 -0
- package/dist/modules/inventory/repository/index.js +310 -0
- package/dist/modules/inventory/schema.d.ts +570 -0
- package/dist/modules/inventory/schema.d.ts.map +1 -0
- package/dist/modules/inventory/schema.js +69 -0
- package/dist/modules/inventory/schemas.d.ts +31 -0
- package/dist/modules/inventory/schemas.d.ts.map +1 -0
- package/dist/modules/inventory/schemas.js +28 -0
- package/dist/modules/inventory/service.d.ts +65 -0
- package/dist/modules/inventory/service.d.ts.map +1 -0
- package/dist/modules/inventory/service.js +271 -0
- package/dist/modules/media/adapter.d.ts +16 -0
- package/dist/modules/media/adapter.d.ts.map +1 -0
- package/dist/modules/media/adapter.js +1 -0
- package/dist/modules/media/repository/in-memory.d.ts +26 -0
- package/dist/modules/media/repository/in-memory.d.ts.map +1 -0
- package/dist/modules/media/repository/in-memory.js +145 -0
- package/dist/modules/media/repository/index.d.ts +35 -0
- package/dist/modules/media/repository/index.d.ts.map +1 -0
- package/dist/modules/media/repository/index.js +176 -0
- package/dist/modules/media/schema.d.ts +289 -0
- package/dist/modules/media/schema.d.ts.map +1 -0
- package/dist/modules/media/schema.js +35 -0
- package/dist/modules/media/service.d.ts +42 -0
- package/dist/modules/media/service.d.ts.map +1 -0
- package/dist/modules/media/service.js +89 -0
- package/dist/modules/orders/repository/in-memory.d.ts +40 -0
- package/dist/modules/orders/repository/in-memory.d.ts.map +1 -0
- package/dist/modules/orders/repository/in-memory.js +245 -0
- package/dist/modules/orders/repository/index.d.ts +48 -0
- package/dist/modules/orders/repository/index.d.ts.map +1 -0
- package/dist/modules/orders/repository/index.js +199 -0
- package/dist/modules/orders/schema.d.ts +672 -0
- package/dist/modules/orders/schema.d.ts.map +1 -0
- package/dist/modules/orders/schema.js +63 -0
- package/dist/modules/orders/service.d.ts +85 -0
- package/dist/modules/orders/service.d.ts.map +1 -0
- package/dist/modules/orders/service.js +313 -0
- package/dist/modules/orders/stale-order-cleanup.d.ts +27 -0
- package/dist/modules/orders/stale-order-cleanup.d.ts.map +1 -0
- package/dist/modules/orders/stale-order-cleanup.js +55 -0
- package/dist/modules/organization/service.d.ts +53 -0
- package/dist/modules/organization/service.d.ts.map +1 -0
- package/dist/modules/organization/service.js +151 -0
- package/dist/modules/payments/adapter.d.ts +42 -0
- package/dist/modules/payments/adapter.d.ts.map +1 -0
- package/dist/modules/payments/adapter.js +1 -0
- package/dist/modules/payments/repository/index.d.ts +5 -0
- package/dist/modules/payments/repository/index.d.ts.map +1 -0
- package/dist/modules/payments/repository/index.js +1 -0
- package/dist/modules/payments/service.d.ts +23 -0
- package/dist/modules/payments/service.d.ts.map +1 -0
- package/dist/modules/payments/service.js +72 -0
- package/dist/modules/pricing/repository/in-memory.d.ts +25 -0
- package/dist/modules/pricing/repository/in-memory.d.ts.map +1 -0
- package/dist/modules/pricing/repository/in-memory.js +288 -0
- package/dist/modules/pricing/repository/index.d.ts +34 -0
- package/dist/modules/pricing/repository/index.d.ts.map +1 -0
- package/dist/modules/pricing/repository/index.js +176 -0
- package/dist/modules/pricing/schema.d.ts +565 -0
- package/dist/modules/pricing/schema.d.ts.map +1 -0
- package/dist/modules/pricing/schema.js +57 -0
- package/dist/modules/pricing/schemas.d.ts +37 -0
- package/dist/modules/pricing/schemas.d.ts.map +1 -0
- package/dist/modules/pricing/schemas.js +30 -0
- package/dist/modules/pricing/service.d.ts +62 -0
- package/dist/modules/pricing/service.d.ts.map +1 -0
- package/dist/modules/pricing/service.js +308 -0
- package/dist/modules/promotions/repository/in-memory.d.ts +32 -0
- package/dist/modules/promotions/repository/in-memory.d.ts.map +1 -0
- package/dist/modules/promotions/repository/in-memory.js +227 -0
- package/dist/modules/promotions/repository/index.d.ts +41 -0
- package/dist/modules/promotions/repository/index.d.ts.map +1 -0
- package/dist/modules/promotions/repository/index.js +204 -0
- package/dist/modules/promotions/schema.d.ts +427 -0
- package/dist/modules/promotions/schema.d.ts.map +1 -0
- package/dist/modules/promotions/schema.js +52 -0
- package/dist/modules/promotions/schemas.d.ts +33 -0
- package/dist/modules/promotions/schemas.d.ts.map +1 -0
- package/dist/modules/promotions/schemas.js +32 -0
- package/dist/modules/promotions/service.d.ts +80 -0
- package/dist/modules/promotions/service.d.ts.map +1 -0
- package/dist/modules/promotions/service.js +347 -0
- package/dist/modules/search/adapter.d.ts +51 -0
- package/dist/modules/search/adapter.d.ts.map +1 -0
- package/dist/modules/search/adapter.js +1 -0
- package/dist/modules/search/hooks.d.ts +8 -0
- package/dist/modules/search/hooks.d.ts.map +1 -0
- package/dist/modules/search/hooks.js +6 -0
- package/dist/modules/search/repository/index.d.ts +5 -0
- package/dist/modules/search/repository/index.d.ts.map +1 -0
- package/dist/modules/search/repository/index.js +1 -0
- package/dist/modules/search/service.d.ts +24 -0
- package/dist/modules/search/service.d.ts.map +1 -0
- package/dist/modules/search/service.js +217 -0
- package/dist/modules/shipping/calculator.d.ts +42 -0
- package/dist/modules/shipping/calculator.d.ts.map +1 -0
- package/dist/modules/shipping/calculator.js +91 -0
- package/dist/modules/shipping/repository/index.d.ts +5 -0
- package/dist/modules/shipping/repository/index.d.ts.map +1 -0
- package/dist/modules/shipping/repository/index.js +1 -0
- package/dist/modules/shipping/service.d.ts +28 -0
- package/dist/modules/shipping/service.d.ts.map +1 -0
- package/dist/modules/shipping/service.js +20 -0
- package/dist/modules/tax/adapter.d.ts +58 -0
- package/dist/modules/tax/adapter.d.ts.map +1 -0
- package/dist/modules/tax/adapter.js +1 -0
- package/dist/modules/tax/repository/index.d.ts +5 -0
- package/dist/modules/tax/repository/index.d.ts.map +1 -0
- package/dist/modules/tax/repository/index.js +1 -0
- package/dist/modules/tax/service.d.ts +19 -0
- package/dist/modules/tax/service.d.ts.map +1 -0
- package/dist/modules/tax/service.js +34 -0
- package/dist/modules/webhooks/hook.d.ts +13 -0
- package/dist/modules/webhooks/hook.d.ts.map +1 -0
- package/dist/modules/webhooks/hook.js +29 -0
- package/dist/modules/webhooks/repository/in-memory.d.ts +31 -0
- package/dist/modules/webhooks/repository/in-memory.d.ts.map +1 -0
- package/dist/modules/webhooks/repository/in-memory.js +187 -0
- package/dist/modules/webhooks/repository/index.d.ts +40 -0
- package/dist/modules/webhooks/repository/index.d.ts.map +1 -0
- package/dist/modules/webhooks/repository/index.js +175 -0
- package/dist/modules/webhooks/schema.d.ts +404 -0
- package/dist/modules/webhooks/schema.d.ts.map +1 -0
- package/dist/modules/webhooks/schema.js +40 -0
- package/dist/modules/webhooks/service.d.ts +23 -0
- package/dist/modules/webhooks/service.d.ts.map +1 -0
- package/dist/modules/webhooks/service.js +92 -0
- package/dist/modules/webhooks/signing.d.ts +2 -0
- package/dist/modules/webhooks/signing.d.ts.map +1 -0
- package/dist/modules/webhooks/signing.js +5 -0
- package/dist/modules/webhooks/ssrf-guard.d.ts +19 -0
- package/dist/modules/webhooks/ssrf-guard.d.ts.map +1 -0
- package/dist/modules/webhooks/ssrf-guard.js +79 -0
- package/dist/modules/webhooks/tasks.d.ts +16 -0
- package/dist/modules/webhooks/tasks.d.ts.map +1 -0
- package/dist/modules/webhooks/tasks.js +35 -0
- package/dist/modules/webhooks/worker.d.ts +21 -0
- package/dist/modules/webhooks/worker.d.ts.map +1 -0
- package/dist/modules/webhooks/worker.js +113 -0
- package/dist/runtime/commerce.d.ts +110 -0
- package/dist/runtime/commerce.d.ts.map +1 -0
- package/dist/runtime/commerce.js +37 -0
- package/dist/runtime/kernel.d.ts +72 -0
- package/dist/runtime/kernel.d.ts.map +1 -0
- package/dist/runtime/kernel.js +298 -0
- package/dist/runtime/logger.d.ts +11 -0
- package/dist/runtime/logger.d.ts.map +1 -0
- package/dist/runtime/logger.js +32 -0
- package/dist/runtime/server.d.ts +28 -0
- package/dist/runtime/server.d.ts.map +1 -0
- package/dist/runtime/server.js +277 -0
- package/dist/runtime/shutdown.d.ts +15 -0
- package/dist/runtime/shutdown.d.ts.map +1 -0
- package/dist/runtime/shutdown.js +34 -0
- package/dist/runtime/state-manager.d.ts +14 -0
- package/dist/runtime/state-manager.d.ts.map +1 -0
- package/dist/runtime/state-manager.js +84 -0
- package/dist/runtime/state-repository.d.ts +13 -0
- package/dist/runtime/state-repository.d.ts.map +1 -0
- package/dist/runtime/state-repository.js +160 -0
- package/dist/runtime/state.d.ts +382 -0
- package/dist/runtime/state.d.ts.map +1 -0
- package/dist/runtime/state.js +37 -0
- package/dist/runtime/store.d.ts +382 -0
- package/dist/runtime/store.d.ts.map +1 -0
- package/dist/runtime/store.js +37 -0
- package/dist/test-utils/create-pglite-adapter.d.ts +32 -0
- package/dist/test-utils/create-pglite-adapter.d.ts.map +1 -0
- package/dist/test-utils/create-pglite-adapter.js +106 -0
- package/dist/test-utils/create-plugin-test-app.d.ts +50 -0
- package/dist/test-utils/create-plugin-test-app.d.ts.map +1 -0
- package/dist/test-utils/create-plugin-test-app.js +74 -0
- package/dist/test-utils/create-repository-test-harness.d.ts +8 -0
- package/dist/test-utils/create-repository-test-harness.d.ts.map +1 -0
- package/dist/test-utils/create-repository-test-harness.js +7 -0
- package/dist/test-utils/create-test-config.d.ts +18 -0
- package/dist/test-utils/create-test-config.d.ts.map +1 -0
- package/dist/test-utils/create-test-config.js +174 -0
- package/dist/test-utils/create-test-kernel.d.ts +3 -0
- package/dist/test-utils/create-test-kernel.d.ts.map +1 -0
- package/dist/test-utils/create-test-kernel.js +5 -0
- package/dist/test-utils/create-test-plugin-context.d.ts +42 -0
- package/dist/test-utils/create-test-plugin-context.d.ts.map +1 -0
- package/dist/test-utils/create-test-plugin-context.js +46 -0
- package/dist/test-utils/rest-api-test-utils.d.ts +64 -0
- package/dist/test-utils/rest-api-test-utils.d.ts.map +1 -0
- package/dist/test-utils/rest-api-test-utils.js +207 -0
- package/dist/test-utils/test-actors.d.ts +15 -0
- package/dist/test-utils/test-actors.d.ts.map +1 -0
- package/dist/test-utils/test-actors.js +57 -0
- package/dist/test-utils/typed-hooks.d.ts +43 -0
- package/dist/test-utils/typed-hooks.d.ts.map +1 -0
- package/dist/test-utils/typed-hooks.js +35 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/commerce-types.d.ts +34 -0
- package/dist/types/commerce-types.d.ts.map +1 -0
- package/dist/types/commerce-types.js +1 -0
- package/dist/utils/id.d.ts +2 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +3 -0
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +16 -0
- package/dist/utils/pagination.d.ts +11 -0
- package/dist/utils/pagination.d.ts.map +1 -0
- package/dist/utils/pagination.js +15 -0
- package/package.json +63 -0
- package/src/adapters/console-email.ts +43 -0
- package/src/auth/access.ts +187 -0
- package/src/auth/auth-schema.ts +131 -0
- package/src/auth/middleware.ts +115 -0
- package/src/auth/org.ts +41 -0
- package/src/auth/permissions.ts +28 -0
- package/src/auth/setup.ts +160 -0
- package/src/auth/system-actor.ts +19 -0
- package/src/auth/types.ts +10 -0
- package/src/config/defaults.ts +82 -0
- package/src/config/define-config.ts +53 -0
- package/src/config/types.ts +299 -0
- package/src/generated/plugin-capabilities.d.ts +20 -0
- package/src/generated/plugin-manifest.ts +23 -0
- package/src/generated/plugin-repositories.d.ts +20 -0
- package/src/hooks/checkout-completion.ts +262 -0
- package/src/hooks/checkout.ts +677 -0
- package/src/hooks/order-emails.ts +62 -0
- package/src/index.ts +214 -0
- package/src/interfaces/mcp/agent-prompt.ts +174 -0
- package/src/interfaces/mcp/context-enrichment.ts +177 -0
- package/src/interfaces/mcp/server.ts +617 -0
- package/src/interfaces/mcp/transport.ts +68 -0
- package/src/interfaces/rest/customer-portal.ts +299 -0
- package/src/interfaces/rest/index.ts +74 -0
- package/src/interfaces/rest/router.ts +334 -0
- package/src/interfaces/rest/routes/admin-jobs.ts +58 -0
- package/src/interfaces/rest/routes/audit.ts +50 -0
- package/src/interfaces/rest/routes/carts.ts +89 -0
- package/src/interfaces/rest/routes/catalog.ts +493 -0
- package/src/interfaces/rest/routes/checkout.ts +283 -0
- package/src/interfaces/rest/routes/inventory.ts +70 -0
- package/src/interfaces/rest/routes/media.ts +86 -0
- package/src/interfaces/rest/routes/orders.ts +78 -0
- package/src/interfaces/rest/routes/payments.ts +60 -0
- package/src/interfaces/rest/routes/pricing.ts +57 -0
- package/src/interfaces/rest/routes/promotions.ts +92 -0
- package/src/interfaces/rest/routes/search.ts +71 -0
- package/src/interfaces/rest/routes/webhooks.ts +46 -0
- package/src/interfaces/rest/schemas/admin-jobs.ts +40 -0
- package/src/interfaces/rest/schemas/audit.ts +46 -0
- package/src/interfaces/rest/schemas/carts.ts +125 -0
- package/src/interfaces/rest/schemas/catalog.ts +450 -0
- package/src/interfaces/rest/schemas/checkout.ts +66 -0
- package/src/interfaces/rest/schemas/customer-portal.ts +195 -0
- package/src/interfaces/rest/schemas/inventory.ts +138 -0
- package/src/interfaces/rest/schemas/media.ts +75 -0
- package/src/interfaces/rest/schemas/orders.ts +104 -0
- package/src/interfaces/rest/schemas/pricing.ts +80 -0
- package/src/interfaces/rest/schemas/promotions.ts +110 -0
- package/src/interfaces/rest/schemas/responses.ts +85 -0
- package/src/interfaces/rest/schemas/search.ts +58 -0
- package/src/interfaces/rest/schemas/shared.ts +62 -0
- package/src/interfaces/rest/schemas/webhooks.ts +68 -0
- package/src/interfaces/rest/utils.ts +104 -0
- package/src/interfaces/rest/webhook-router.ts +50 -0
- package/src/kernel/compensation/executor.ts +61 -0
- package/src/kernel/compensation/types.ts +26 -0
- package/src/kernel/database/adapter.ts +13 -0
- package/src/kernel/database/drizzle-db.ts +56 -0
- package/src/kernel/database/migrate.ts +76 -0
- package/src/kernel/database/plugin-types.ts +34 -0
- package/src/kernel/database/schema.ts +49 -0
- package/src/kernel/database/scoped-db.ts +68 -0
- package/src/kernel/database/tx-context.ts +46 -0
- package/src/kernel/error-mapper.ts +15 -0
- package/src/kernel/errors.ts +89 -0
- package/src/kernel/factory/repository-factory.ts +242 -0
- package/src/kernel/hooks/create-context.ts +43 -0
- package/src/kernel/hooks/executor.ts +88 -0
- package/src/kernel/hooks/registry.ts +74 -0
- package/src/kernel/hooks/types.ts +52 -0
- package/src/kernel/http-error.ts +44 -0
- package/src/kernel/jobs/adapter.ts +36 -0
- package/src/kernel/jobs/drizzle-adapter.ts +58 -0
- package/src/kernel/jobs/runner.ts +153 -0
- package/src/kernel/jobs/schema.ts +46 -0
- package/src/kernel/jobs/types.ts +30 -0
- package/src/kernel/local-api.ts +185 -0
- package/src/kernel/plugin/manifest.ts +253 -0
- package/src/kernel/query/executor.ts +184 -0
- package/src/kernel/query/registry.ts +46 -0
- package/src/kernel/result.ts +33 -0
- package/src/kernel/schema/extra-columns.ts +37 -0
- package/src/kernel/service-registry.ts +76 -0
- package/src/kernel/service-timing.ts +89 -0
- package/src/kernel/state-machine/machine.ts +101 -0
- package/src/modules/analytics/drizzle-adapter.ts +426 -0
- package/src/modules/analytics/hooks.ts +11 -0
- package/src/modules/analytics/models.ts +125 -0
- package/src/modules/analytics/repository/index.ts +6 -0
- package/src/modules/analytics/service.ts +245 -0
- package/src/modules/analytics/types.ts +180 -0
- package/src/modules/audit/hooks.ts +78 -0
- package/src/modules/audit/schema.ts +33 -0
- package/src/modules/audit/service.ts +151 -0
- package/src/modules/cart/access.ts +27 -0
- package/src/modules/cart/matcher.ts +26 -0
- package/src/modules/cart/repository/index.ts +234 -0
- package/src/modules/cart/schema.ts +42 -0
- package/src/modules/cart/schemas.ts +38 -0
- package/src/modules/cart/service.ts +541 -0
- package/src/modules/catalog/repository/index.ts +772 -0
- package/src/modules/catalog/schema.ts +203 -0
- package/src/modules/catalog/schemas.ts +104 -0
- package/src/modules/catalog/service.ts +1544 -0
- package/src/modules/customers/repository/index.ts +327 -0
- package/src/modules/customers/schema.ts +64 -0
- package/src/modules/customers/service.ts +171 -0
- package/src/modules/fulfillment/repository/index.ts +426 -0
- package/src/modules/fulfillment/schema.ts +101 -0
- package/src/modules/fulfillment/service.ts +555 -0
- package/src/modules/fulfillment/types.ts +59 -0
- package/src/modules/inventory/repository/index.ts +509 -0
- package/src/modules/inventory/schema.ts +94 -0
- package/src/modules/inventory/schemas.ts +38 -0
- package/src/modules/inventory/service.ts +490 -0
- package/src/modules/media/adapter.ts +17 -0
- package/src/modules/media/repository/index.ts +274 -0
- package/src/modules/media/schema.ts +41 -0
- package/src/modules/media/service.ts +151 -0
- package/src/modules/orders/repository/index.ts +287 -0
- package/src/modules/orders/schema.ts +66 -0
- package/src/modules/orders/service.ts +619 -0
- package/src/modules/orders/stale-order-cleanup.ts +76 -0
- package/src/modules/organization/service.ts +191 -0
- package/src/modules/payments/adapter.ts +47 -0
- package/src/modules/payments/repository/index.ts +6 -0
- package/src/modules/payments/service.ts +107 -0
- package/src/modules/pricing/repository/index.ts +291 -0
- package/src/modules/pricing/schema.ts +71 -0
- package/src/modules/pricing/schemas.ts +38 -0
- package/src/modules/pricing/service.ts +494 -0
- package/src/modules/promotions/repository/index.ts +325 -0
- package/src/modules/promotions/schema.ts +62 -0
- package/src/modules/promotions/schemas.ts +38 -0
- package/src/modules/promotions/service.ts +598 -0
- package/src/modules/search/adapter.ts +57 -0
- package/src/modules/search/hooks.ts +12 -0
- package/src/modules/search/repository/index.ts +6 -0
- package/src/modules/search/service.ts +315 -0
- package/src/modules/shipping/calculator.ts +188 -0
- package/src/modules/shipping/repository/index.ts +6 -0
- package/src/modules/shipping/service.ts +51 -0
- package/src/modules/tax/adapter.ts +60 -0
- package/src/modules/tax/repository/index.ts +6 -0
- package/src/modules/tax/service.ts +53 -0
- package/src/modules/webhooks/hook.ts +34 -0
- package/src/modules/webhooks/repository/index.ts +278 -0
- package/src/modules/webhooks/schema.ts +56 -0
- package/src/modules/webhooks/service.ts +117 -0
- package/src/modules/webhooks/signing.ts +6 -0
- package/src/modules/webhooks/ssrf-guard.ts +71 -0
- package/src/modules/webhooks/tasks.ts +52 -0
- package/src/modules/webhooks/worker.ts +134 -0
- package/src/runtime/commerce.ts +145 -0
- package/src/runtime/kernel.ts +419 -0
- package/src/runtime/logger.ts +36 -0
- package/src/runtime/server.ts +345 -0
- package/src/runtime/shutdown.ts +43 -0
- package/src/test-utils/create-pglite-adapter.ts +129 -0
- package/src/test-utils/create-plugin-test-app.ts +128 -0
- package/src/test-utils/create-repository-test-harness.ts +16 -0
- package/src/test-utils/create-test-config.ts +190 -0
- package/src/test-utils/create-test-kernel.ts +7 -0
- package/src/test-utils/create-test-plugin-context.ts +75 -0
- package/src/test-utils/rest-api-test-utils.ts +265 -0
- package/src/test-utils/test-actors.ts +62 -0
- package/src/test-utils/typed-hooks.ts +54 -0
- package/src/types/commerce-types.ts +34 -0
- package/src/utils/id.ts +3 -0
- package/src/utils/logger.ts +18 -0
- package/src/utils/pagination.ts +22 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/auth/auth-schema.ts", "../src/modules/organization/service.ts", "../src/auth/org.ts", "../src/modules/catalog/schema.ts", "../src/modules/orders/schema.ts", "../src/modules/cart/schema.ts", "../src/modules/customers/schema.ts", "../src/kernel/jobs/schema.ts", "../src/modules/webhooks/schema.ts", "../src/modules/inventory/schema.ts", "../src/modules/pricing/schema.ts", "../src/modules/promotions/schema.ts", "../src/modules/fulfillment/schema.ts", "../src/modules/media/schema.ts", "../src/modules/audit/schema.ts", "../src/kernel/jobs/runner.ts", "../src/kernel/database/schema.ts", "../src/kernel/database/migrate.ts", "../src/test-utils/create-pglite-adapter.ts", "../src/config/defaults.ts", "../src/kernel/plugin/manifest.ts", "../src/config/define-config.ts", "../src/interfaces/rest/router.ts", "../src/interfaces/rest/schemas/shared.ts", "../src/kernel/errors.ts", "../src/kernel/error-mapper.ts", "../src/interfaces/rest/utils.ts", "../src/kernel/database/scoped-db.ts", "../src/interfaces/rest/webhook-router.ts", "../src/modules/webhooks/ssrf-guard.ts", "../src/runtime/server.ts", "../src/auth/middleware.ts", "../src/interfaces/mcp/transport.ts", "../src/modules/analytics/types.ts", "../src/kernel/state-machine/machine.ts", "../src/interfaces/mcp/context-enrichment.ts", "../src/interfaces/mcp/server.ts", "../src/interfaces/rest/index.ts", "../src/interfaces/rest/routes/catalog.ts", "../src/interfaces/rest/schemas/catalog.ts", "../src/interfaces/rest/schemas/responses.ts", "../src/modules/catalog/schemas.ts", "../src/interfaces/rest/routes/inventory.ts", "../src/interfaces/rest/schemas/inventory.ts", "../src/modules/inventory/schemas.ts", "../src/interfaces/rest/routes/media.ts", "../src/interfaces/rest/schemas/media.ts", "../src/interfaces/rest/routes/carts.ts", "../src/interfaces/rest/schemas/carts.ts", "../src/modules/cart/schemas.ts", "../src/interfaces/rest/routes/checkout.ts", "../src/interfaces/rest/schemas/checkout.ts", "../src/kernel/compensation/executor.ts", "../src/kernel/result.ts", "../src/hooks/checkout-completion.ts", "../src/hooks/checkout.ts", "../src/kernel/hooks/executor.ts", "../src/kernel/hooks/create-context.ts", "../src/kernel/jobs/adapter.ts", "../src/utils/id.ts", "../src/interfaces/rest/routes/orders.ts", "../src/interfaces/rest/schemas/orders.ts", "../src/interfaces/rest/routes/payments.ts", "../src/interfaces/rest/routes/webhooks.ts", "../src/interfaces/rest/schemas/webhooks.ts", "../src/interfaces/rest/routes/pricing.ts", "../src/interfaces/rest/schemas/pricing.ts", "../src/modules/pricing/schemas.ts", "../src/interfaces/rest/routes/promotions.ts", "../src/interfaces/rest/schemas/promotions.ts", "../src/modules/promotions/schemas.ts", "../src/interfaces/rest/routes/search.ts", "../src/interfaces/rest/schemas/search.ts", "../src/interfaces/rest/routes/audit.ts", "../src/interfaces/rest/schemas/audit.ts", "../src/interfaces/rest/routes/admin-jobs.ts", "../src/interfaces/rest/schemas/admin-jobs.ts", "../src/interfaces/rest/customer-portal.ts", "../src/auth/permissions.ts", "../src/interfaces/rest/schemas/customer-portal.ts", "../src/kernel/hooks/registry.ts", "../src/kernel/database/adapter.ts", "../src/modules/catalog/service.ts", "../src/utils/logger.ts", "../src/utils/pagination.ts", "../src/modules/catalog/repository/index.ts", "../src/modules/inventory/repository/index.ts", "../src/modules/cart/repository/index.ts", "../src/modules/orders/repository/index.ts", "../src/modules/customers/repository/index.ts", "../src/modules/pricing/repository/index.ts", "../src/modules/promotions/repository/index.ts", "../src/modules/fulfillment/repository/index.ts", "../src/modules/webhooks/repository/index.ts", "../src/modules/media/repository/index.ts", "../src/modules/inventory/service.ts", "../src/kernel/database/tx-context.ts", "../src/modules/media/service.ts", "../src/modules/cart/service.ts", "../src/modules/cart/matcher.ts", "../src/modules/orders/service.ts", "../src/modules/payments/service.ts", "../src/modules/fulfillment/service.ts", "../src/modules/customers/service.ts", "../src/modules/webhooks/service.ts", "../src/modules/analytics/service.ts", "../src/modules/analytics/drizzle-adapter.ts", "../src/modules/analytics/models.ts", "../src/modules/pricing/service.ts", "../src/modules/promotions/service.ts", "../src/modules/tax/service.ts", "../src/modules/shipping/calculator.ts", "../src/modules/shipping/service.ts", "../src/modules/search/service.ts", "../src/modules/webhooks/signing.ts", "../src/modules/webhooks/worker.ts", "../src/modules/audit/service.ts", "../src/runtime/kernel.ts", "../src/kernel/service-timing.ts", "../src/modules/webhooks/hook.ts", "../src/modules/search/hooks.ts", "../src/modules/audit/hooks.ts", "../src/hooks/order-emails.ts", "../src/kernel/jobs/drizzle-adapter.ts", "../src/runtime/commerce.ts", "../src/auth/setup.ts", "../src/runtime/logger.ts", "../src/kernel/local-api.ts", "../src/runtime/shutdown.ts", "../src/test-utils/create-test-config.ts", "../src/test-utils/create-test-kernel.ts", "../src/test-utils/create-test-plugin-context.ts", "../src/test-utils/create-repository-test-harness.ts", "../src/test-utils/create-plugin-test-app.ts", "../src/test-utils/test-actors.ts", "../src/test-utils/typed-hooks.ts", "../src/index.ts", "../src/auth/access.ts", "../src/kernel/http-error.ts", "../src/adapters/console-email.ts", "../src/kernel/factory/repository-factory.ts", "../src/kernel/schema/extra-columns.ts", "../src/modules/cart/access.ts", "../src/kernel/query/registry.ts", "../src/kernel/query/executor.ts", "../src/modules/orders/stale-order-cleanup.ts", "../src/interfaces/mcp/agent-prompt.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import {\n pgTable,\n text,\n timestamp,\n boolean,\n integer,\n} from \"drizzle-orm/pg-core\";\n\nexport const user = pgTable(\"user\", {\n id: text(\"id\").primaryKey(),\n name: text(\"name\").notNull(),\n email: text(\"email\").notNull().unique(),\n emailVerified: boolean(\"email_verified\").default(false).notNull(),\n image: text(\"image\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\")\n .defaultNow()\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n vendorId: text(\"vendor_id\"),\n posOperatorPin: text(\"pos_operator_pin\"),\n});\n\nexport const session = pgTable(\"session\", {\n id: text(\"id\").primaryKey(),\n expiresAt: timestamp(\"expires_at\").notNull(),\n token: text(\"token\").notNull().unique(),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\")\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n ipAddress: text(\"ip_address\"),\n userAgent: text(\"user_agent\"),\n userId: text(\"user_id\")\n .notNull()\n .references(() => user.id, { onDelete: \"cascade\" }),\n activeOrganizationId: text(\"active_organization_id\"),\n});\n\nexport const account = pgTable(\"account\", {\n id: text(\"id\").primaryKey(),\n accountId: text(\"account_id\").notNull(),\n providerId: text(\"provider_id\").notNull(),\n userId: text(\"user_id\")\n .notNull()\n .references(() => user.id, { onDelete: \"cascade\" }),\n accessToken: text(\"access_token\"),\n refreshToken: text(\"refresh_token\"),\n idToken: text(\"id_token\"),\n accessTokenExpiresAt: timestamp(\"access_token_expires_at\"),\n refreshTokenExpiresAt: timestamp(\"refresh_token_expires_at\"),\n scope: text(\"scope\"),\n password: text(\"password\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\")\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n});\n\nexport const verification = pgTable(\"verification\", {\n id: text(\"id\").primaryKey(),\n identifier: text(\"identifier\").notNull(),\n value: text(\"value\").notNull(),\n expiresAt: timestamp(\"expires_at\").notNull(),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\")\n .defaultNow()\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n});\n\nexport const organization = pgTable(\"organization\", {\n id: text(\"id\").primaryKey(),\n name: text(\"name\").notNull(),\n slug: text(\"slug\").notNull().unique(),\n logo: text(\"logo\"),\n createdAt: timestamp(\"created_at\").notNull(),\n metadata: text(\"metadata\"),\n});\n\nexport const member = pgTable(\"member\", {\n id: text(\"id\").primaryKey(),\n organizationId: text(\"organization_id\")\n .notNull()\n .references(() => organization.id, { onDelete: \"cascade\" }),\n userId: text(\"user_id\")\n .notNull()\n .references(() => user.id, { onDelete: \"cascade\" }),\n role: text(\"role\").default(\"member\").notNull(),\n createdAt: timestamp(\"created_at\").notNull(),\n});\n\nexport const invitation = pgTable(\"invitation\", {\n id: text(\"id\").primaryKey(),\n organizationId: text(\"organization_id\")\n .notNull()\n .references(() => organization.id, { onDelete: \"cascade\" }),\n email: text(\"email\").notNull(),\n role: text(\"role\"),\n status: text(\"status\").default(\"pending\").notNull(),\n expiresAt: timestamp(\"expires_at\").notNull(),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n inviterId: text(\"inviter_id\")\n .notNull()\n .references(() => user.id, { onDelete: \"cascade\" }),\n});\n\nexport const apikey = pgTable(\"apikey\", {\n id: text(\"id\").primaryKey(),\n configId: text(\"config_id\").default(\"default\").notNull(),\n name: text(\"name\"),\n start: text(\"start\"),\n referenceId: text(\"reference_id\").notNull(),\n prefix: text(\"prefix\"),\n key: text(\"key\").notNull(),\n refillInterval: integer(\"refill_interval\"),\n refillAmount: integer(\"refill_amount\"),\n lastRefillAt: timestamp(\"last_refill_at\"),\n enabled: boolean(\"enabled\").default(true),\n rateLimitEnabled: boolean(\"rate_limit_enabled\").default(true),\n rateLimitTimeWindow: integer(\"rate_limit_time_window\").default(86400000),\n rateLimitMax: integer(\"rate_limit_max\").default(10),\n requestCount: integer(\"request_count\").default(0),\n remaining: integer(\"remaining\"),\n lastRequest: timestamp(\"last_request\"),\n expiresAt: timestamp(\"expires_at\"),\n createdAt: timestamp(\"created_at\").notNull(),\n updatedAt: timestamp(\"updated_at\").notNull(),\n permissions: text(\"permissions\"),\n metadata: text(\"metadata\"),\n});\n",
|
|
6
|
+
"/**\n * OrganizationService — wraps Better Auth's server-side organization API.\n *\n * When auth.api is available (server context), uses Better Auth's\n * createOrganization which properly creates org + member records.\n *\n * When auth is not available (kernel-only scripts), falls back to\n * direct Drizzle insert into the organization table.\n */\n\nimport { eq } from \"drizzle-orm\";\nimport type { PgDatabase, PgQueryResultHKT } from \"drizzle-orm/pg-core\";\nimport { organization, member } from \"../../auth/auth-schema\";\nimport type { AuthInstance } from \"../../auth/setup\";\n\ntype DrizzleDb = PgDatabase<PgQueryResultHKT, Record<string, unknown>>;\n\ninterface Result<T> { ok: true; value: T }\ninterface ResultErr { ok: false; error: string }\nfunction Ok<T>(value: T): Result<T> { return { ok: true, value }; }\nfunction Err(error: string): ResultErr { return { ok: false, error }; }\n\nexport interface Organization {\n id: string;\n name: string;\n slug: string;\n logo?: string | null;\n metadata?: string | null;\n createdAt: Date;\n}\n\nexport interface OrganizationCreateInput {\n id?: string;\n name: string;\n slug: string;\n userId?: string;\n logo?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport class OrganizationService {\n private auth: AuthInstance | null;\n private db: DrizzleDb;\n\n constructor(db: unknown, auth?: AuthInstance | null) {\n this.db = db as DrizzleDb;\n this.auth = auth ?? null;\n }\n\n /**\n * Create an organization.\n *\n * If auth.api is available, uses Better Auth's createOrganization\n * which creates both the org and a member record for the creator.\n *\n * If auth is not available, falls back to direct Drizzle insert\n * and manually creates a member record if userId is provided.\n */\n async create(input: OrganizationCreateInput): Promise<Result<Organization> | ResultErr> {\n // Try Better Auth server-side API first\n if (this.auth) {\n try {\n const api = this.auth.api as Record<string, unknown>;\n if (typeof api.createOrganization === \"function\") {\n const result = await (api.createOrganization as (opts: unknown) => Promise<unknown>)({\n body: {\n name: input.name,\n slug: input.slug,\n logo: input.logo,\n metadata: input.metadata ? JSON.stringify(input.metadata) : undefined,\n ...(input.userId ? { userId: input.userId } : {}),\n },\n });\n\n const org = result as Record<string, unknown>;\n return Ok({\n id: String(org.id ?? \"\"),\n name: String(org.name ?? \"\"),\n slug: String(org.slug ?? \"\"),\n logo: org.logo as string | null,\n metadata: org.metadata as string | null,\n createdAt: org.createdAt instanceof Date ? org.createdAt : new Date(),\n });\n }\n } catch (err) {\n // If Better Auth throws (e.g., slug conflict), handle gracefully\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes(\"already exists\") || message.includes(\"UNIQUE\")) {\n return Err(`Organization with slug \"${input.slug}\" already exists`);\n }\n // Fall through to Drizzle fallback\n }\n }\n\n // Fallback: direct Drizzle insert\n const orgId = input.id ?? crypto.randomUUID().replace(/-/g, \"\").slice(0, 32);\n\n // Check if already exists\n const existing = await this.db\n .select({ id: organization.id })\n .from(organization)\n .where(eq(organization.id, orgId));\n\n if (existing.length > 0) {\n return Ok({\n id: existing[0]!.id,\n name: input.name,\n slug: input.slug,\n logo: null,\n metadata: null,\n createdAt: new Date(),\n });\n }\n\n const existingSlug = await this.db\n .select({ id: organization.id })\n .from(organization)\n .where(eq(organization.slug, input.slug));\n\n if (existingSlug.length > 0) {\n return Ok({\n id: existingSlug[0]!.id,\n name: input.name,\n slug: input.slug,\n logo: null,\n metadata: null,\n createdAt: new Date(),\n });\n }\n\n await this.db.insert(organization).values({\n id: orgId,\n name: input.name,\n slug: input.slug,\n logo: input.logo,\n metadata: input.metadata ? JSON.stringify(input.metadata) : undefined,\n createdAt: new Date(),\n });\n\n // Create member record for the creator\n if (input.userId) {\n await this.db.insert(member).values({\n id: crypto.randomUUID().replace(/-/g, \"\").slice(0, 32),\n organizationId: orgId,\n userId: input.userId,\n role: \"owner\",\n createdAt: new Date(),\n });\n }\n\n return Ok({\n id: orgId,\n name: input.name,\n slug: input.slug,\n logo: input.logo ?? null,\n metadata: input.metadata ? JSON.stringify(input.metadata) : null,\n createdAt: new Date(),\n });\n }\n\n async getById(id: string): Promise<Result<Organization> | ResultErr> {\n const rows = await this.db\n .select()\n .from(organization)\n .where(eq(organization.id, id));\n\n if (rows.length === 0) return Err(\"Organization not found\");\n\n const org = rows[0]!;\n return Ok({\n id: org.id,\n name: org.name,\n slug: org.slug,\n logo: org.logo,\n metadata: org.metadata,\n createdAt: org.createdAt,\n });\n }\n\n async list(): Promise<Result<Organization[]>> {\n const rows = await this.db.select().from(organization);\n return Ok(rows.map(org => ({\n id: org.id,\n name: org.name,\n slug: org.slug,\n logo: org.logo,\n metadata: org.metadata,\n createdAt: org.createdAt,\n })));\n }\n}\n",
|
|
7
|
+
"import { OrganizationService } from \"../modules/organization/service\";\n\n/**\n * Deterministic ID for the default organization.\n * Auto-created on kernel boot / test setup for single-tenant deployments.\n */\nexport const DEFAULT_ORG_ID = \"org_default\";\n\n/**\n * Extracts the organization ID from an actor.\n * Falls back to the default org when the actor is null or has no org set.\n */\nexport function resolveOrgId(actor: unknown): string {\n if (actor != null && typeof actor === \"object\" && \"organizationId\" in actor) {\n const orgId = (actor as { organizationId: unknown }).organizationId;\n if (typeof orgId === \"string\") return orgId;\n }\n return DEFAULT_ORG_ID;\n}\n\n/**\n * Ensures the default organization row exists in the database.\n * Idempotent — safe to call multiple times (no-ops if the row exists).\n *\n * Uses OrganizationService which creates both the org row and\n * (when auth is available) a member record for the creator.\n *\n * Accepts `unknown` so callers never need casts — the function\n * handles the Drizzle type narrowing internally.\n */\nexport async function ensureDefaultOrg(\n db: unknown,\n storeName = \"Default Store\",\n): Promise<void> {\n const orgService = new OrganizationService(db);\n await orgService.create({\n id: DEFAULT_ORG_ID,\n name: storeName,\n slug: \"default\",\n });\n}\n",
|
|
8
|
+
"import type { AnyPgColumn } from \"drizzle-orm/pg-core\";\nimport {\n boolean,\n index,\n integer,\n jsonb,\n pgTable,\n text,\n timestamp,\n uniqueIndex,\n uuid,\n} from \"drizzle-orm/pg-core\";\nimport { organization } from \"../../auth/auth-schema\";\n\nexport const sellableEntities = pgTable(\n \"sellable_entities\",\n {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n organizationId: text(\"organization_id\").notNull().references(() => organization.id, { onDelete: \"cascade\" }),\n type: text(\"type\").notNull(),\n slug: text(\"slug\").notNull(),\n status: text(\"status\", {\n enum: [\"draft\", \"active\", \"archived\", \"discontinued\"],\n })\n .notNull()\n .default(\"draft\"),\n isVisible: boolean(\"is_visible\").notNull().default(false),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n createdAt: timestamp(\"created_at\", { withTimezone: true }).defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true }).defaultNow().notNull(),\n publishedAt: timestamp(\"published_at\", { withTimezone: true }),\n },\n (table) => ({\n typeIdx: index(\"idx_sellable_entities_type\").on(table.type),\n statusIdx: index(\"idx_sellable_entities_status\").on(table.status),\n slugIdx: index(\"idx_sellable_entities_slug\").on(table.slug),\n orgIdx: index(\"idx_sellable_entities_org\").on(table.organizationId),\n orgSlugUnique: uniqueIndex(\"sellable_entities_org_slug_unique\").on(table.organizationId, table.slug),\n }),\n);\n\nexport const sellableAttributes = pgTable(\n \"sellable_attributes\",\n {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n entityId: uuid(\"entity_id\")\n .references(() => sellableEntities.id, { onDelete: \"cascade\" })\n .notNull(),\n locale: text(\"locale\").notNull().default(\"en\"),\n title: text(\"title\").notNull(),\n subtitle: text(\"subtitle\"),\n description: text(\"description\"),\n richDescription: jsonb(\"rich_description\"),\n seoTitle: text(\"seo_title\"),\n seoDescription: text(\"seo_description\"),\n },\n (table) => ({\n entityLocaleIdx: index(\"idx_sellable_attrs_entity_locale\").on(\n table.entityId,\n table.locale,\n ),\n }),\n);\n\nexport const sellableCustomFields = pgTable(\n \"sellable_custom_fields\",\n {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n entityId: uuid(\"entity_id\")\n .references(() => sellableEntities.id, { onDelete: \"cascade\" })\n .notNull(),\n fieldName: text(\"field_name\").notNull(),\n fieldType: text(\"field_type\", {\n enum: [\"text\", \"number\", \"boolean\", \"date\", \"json\", \"relation\"],\n }).notNull(),\n textValue: text(\"text_value\"),\n numberValue: integer(\"number_value\"),\n booleanValue: boolean(\"boolean_value\"),\n dateValue: timestamp(\"date_value\", { withTimezone: true }),\n jsonValue: jsonb(\"json_value\"),\n },\n (table) => ({\n entityFieldIdx: index(\"idx_custom_fields_entity_field\").on(\n table.entityId,\n table.fieldName,\n ),\n textValueIdx: index(\"idx_custom_fields_text\").on(\n table.fieldName,\n table.textValue,\n ),\n numberValueIdx: index(\"idx_custom_fields_number\").on(\n table.fieldName,\n table.numberValue,\n ),\n }),\n);\n\nexport const categories = pgTable(\n \"categories\",\n {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n organizationId: text(\"organization_id\").notNull().references(() => organization.id, { onDelete: \"cascade\" }),\n // Self-referential FK — Drizzle requires AnyPgColumn for circular references.\n parentId: uuid(\"parent_id\").references((): AnyPgColumn => categories.id, {\n onDelete: \"set null\",\n }),\n slug: text(\"slug\").notNull(),\n sortOrder: integer(\"sort_order\").notNull().default(0),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n },\n (table) => ({\n orgIdx: index(\"idx_categories_org\").on(table.organizationId),\n orgSlugUnique: uniqueIndex(\"categories_org_slug_unique\").on(table.organizationId, table.slug),\n }),\n);\n\nexport const entityCategories = pgTable(\"entity_categories\", {\n entityId: uuid(\"entity_id\")\n .references(() => sellableEntities.id, { onDelete: \"cascade\" })\n .notNull(),\n categoryId: uuid(\"category_id\")\n .references(() => categories.id, { onDelete: \"cascade\" })\n .notNull(),\n sortOrder: integer(\"sort_order\").notNull().default(0),\n}, (table) => ({\n entityCategoryUnique: uniqueIndex(\"entity_categories_entity_category_unique\").on(table.entityId, table.categoryId),\n}));\n\nexport const brands = pgTable(\n \"brands\",\n {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n organizationId: text(\"organization_id\").notNull().references(() => organization.id, { onDelete: \"cascade\" }),\n slug: text(\"slug\").notNull(),\n displayName: text(\"display_name\").notNull(),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n },\n (table) => ({\n orgIdx: index(\"idx_brands_org\").on(table.organizationId),\n orgSlugUnique: uniqueIndex(\"brands_org_slug_unique\").on(table.organizationId, table.slug),\n }),\n);\n\nexport const entityBrands = pgTable(\"entity_brands\", {\n entityId: uuid(\"entity_id\")\n .references(() => sellableEntities.id, { onDelete: \"cascade\" })\n .notNull(),\n brandId: uuid(\"brand_id\")\n .references(() => brands.id, { onDelete: \"cascade\" })\n .notNull(),\n sortOrder: integer(\"sort_order\").notNull().default(0),\n}, (table) => ({\n entityBrandUnique: uniqueIndex(\"entity_brands_entity_brand_unique\").on(table.entityId, table.brandId),\n}));\n\nexport const optionTypes = pgTable(\"option_types\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n entityId: uuid(\"entity_id\")\n .references(() => sellableEntities.id, { onDelete: \"cascade\" })\n .notNull(),\n name: text(\"name\").notNull(),\n displayName: text(\"display_name\").notNull(),\n sortOrder: integer(\"sort_order\").notNull().default(0),\n});\n\nexport const optionValues = pgTable(\"option_values\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n optionTypeId: uuid(\"option_type_id\")\n .references(() => optionTypes.id, { onDelete: \"cascade\" })\n .notNull(),\n value: text(\"value\").notNull(),\n displayValue: text(\"display_value\").notNull(),\n sortOrder: integer(\"sort_order\").notNull().default(0),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n});\n\nexport const variants = pgTable(\"variants\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n entityId: uuid(\"entity_id\")\n .references(() => sellableEntities.id, { onDelete: \"cascade\" })\n .notNull(),\n sku: text(\"sku\").unique(),\n barcode: text(\"barcode\"),\n status: text(\"status\", { enum: [\"active\", \"discontinued\"] })\n .notNull()\n .default(\"active\"),\n sortOrder: integer(\"sort_order\").notNull().default(0),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n}, (table) => ({\n barcodeIdx: index(\"idx_variants_barcode\").on(table.barcode),\n skuIdx: index(\"idx_variants_sku\").on(table.sku),\n}));\n\nexport const variantOptionValues = pgTable(\"variant_option_values\", {\n variantId: uuid(\"variant_id\")\n .references(() => variants.id, { onDelete: \"cascade\" })\n .notNull(),\n optionValueId: uuid(\"option_value_id\")\n .references(() => optionValues.id, { onDelete: \"cascade\" })\n .notNull(),\n}, (table) => ({\n variantOptionValueUnique: uniqueIndex(\"variant_option_values_variant_option_unique\").on(table.variantId, table.optionValueId),\n}));\n",
|
|
9
|
+
"import { index, integer, jsonb, pgTable, text, timestamp, uniqueIndex, uuid } from \"drizzle-orm/pg-core\";\nimport { organization } from \"../../auth/auth-schema\";\nimport { sellableEntities, variants } from \"../catalog/schema\";\n\nexport const orders = pgTable(\"orders\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n organizationId: text(\"organization_id\").notNull().references(() => organization.id, { onDelete: \"cascade\" }),\n orderNumber: text(\"order_number\").notNull(),\n customerId: uuid(\"customer_id\"),\n status: text(\"status\").notNull().default(\"pending\"),\n currency: text(\"currency\").notNull(),\n subtotal: integer(\"subtotal\").notNull(),\n taxTotal: integer(\"tax_total\").notNull(),\n shippingTotal: integer(\"shipping_total\").notNull(),\n discountTotal: integer(\"discount_total\").notNull().default(0),\n grandTotal: integer(\"grand_total\").notNull(),\n paymentIntentId: text(\"payment_intent_id\"),\n paymentMethodId: text(\"payment_method_id\"),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n placedAt: timestamp(\"placed_at\", { withTimezone: true }).defaultNow().notNull(),\n fulfilledAt: timestamp(\"fulfilled_at\", { withTimezone: true }),\n cancelledAt: timestamp(\"cancelled_at\", { withTimezone: true }),\n}, (table) => ({\n orgIdx: index(\"idx_orders_org\").on(table.organizationId),\n orgOrderNumberUnique: uniqueIndex(\"orders_org_order_number_unique\").on(table.organizationId, table.orderNumber),\n statusIdx: index(\"idx_orders_status\").on(table.status),\n customerIdIdx: index(\"idx_orders_customer_id\").on(table.customerId),\n placedAtIdx: index(\"idx_orders_placed_at\").on(table.placedAt),\n paymentIntentIdx: index(\"idx_orders_payment_intent\").on(table.paymentIntentId),\n}));\n\nexport const orderLineItems = pgTable(\"order_line_items\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n orderId: uuid(\"order_id\")\n .references(() => orders.id, { onDelete: \"cascade\" })\n .notNull(),\n entityId: uuid(\"entity_id\").references(() => sellableEntities.id).notNull(),\n entityType: text(\"entity_type\").notNull(),\n variantId: uuid(\"variant_id\").references(() => variants.id),\n sku: text(\"sku\"),\n title: text(\"title\").notNull(),\n quantity: integer(\"quantity\").notNull(),\n unitPrice: integer(\"unit_price\").notNull(),\n totalPrice: integer(\"total_price\").notNull(),\n taxAmount: integer(\"tax_amount\").notNull().default(0),\n discountAmount: integer(\"discount_amount\").notNull().default(0),\n fulfillmentStatus: text(\"fulfillment_status\").notNull().default(\"unfulfilled\"),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n}, (table) => [\n index(\"idx_order_line_items_order_id\").on(table.orderId),\n index(\"idx_order_line_items_entity_id\").on(table.entityId),\n]);\n\nexport const orderStatusHistory = pgTable(\"order_status_history\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n orderId: uuid(\"order_id\")\n .references(() => orders.id, { onDelete: \"cascade\" })\n .notNull(),\n fromStatus: text(\"from_status\").notNull(),\n toStatus: text(\"to_status\").notNull(),\n reason: text(\"reason\"),\n changedBy: text(\"changed_by\").notNull(),\n changedAt: timestamp(\"changed_at\", { withTimezone: true }).defaultNow().notNull(),\n}, (table) => [\n index(\"idx_order_status_history_order_id\").on(table.orderId),\n]);\n",
|
|
10
|
+
"import { index, integer, jsonb, pgTable, text, timestamp, uuid } from \"drizzle-orm/pg-core\";\nimport { organization } from \"../../auth/auth-schema\";\nimport { sellableEntities, variants } from \"../catalog/schema\";\n\nexport const carts = pgTable(\"carts\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n organizationId: text(\"organization_id\").notNull().references(() => organization.id, { onDelete: \"cascade\" }),\n customerId: uuid(\"customer_id\"),\n status: text(\"status\", {\n enum: [\"active\", \"checking_out\", \"merged\", \"checked_out\", \"abandoned\"],\n })\n .notNull()\n .default(\"active\"),\n currency: text(\"currency\").notNull().default(\"USD\"),\n secret: text(\"secret\"),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n expiresAt: timestamp(\"expires_at\", { withTimezone: true }).notNull(),\n createdAt: timestamp(\"created_at\", { withTimezone: true }).defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true }).defaultNow().notNull(),\n}, (table) => ({\n orgIdx: index(\"idx_carts_org\").on(table.organizationId),\n customerIdIdx: index(\"idx_carts_customer_id\").on(table.customerId),\n statusIdx: index(\"idx_carts_status\").on(table.status),\n expiresAtIdx: index(\"idx_carts_expires_at\").on(table.expiresAt),\n}));\n\nexport const cartLineItems = pgTable(\"cart_line_items\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n cartId: uuid(\"cart_id\")\n .references(() => carts.id, { onDelete: \"cascade\" })\n .notNull(),\n entityId: uuid(\"entity_id\").references(() => sellableEntities.id).notNull(),\n variantId: uuid(\"variant_id\").references(() => variants.id),\n quantity: integer(\"quantity\").notNull().default(1),\n unitPriceSnapshot: integer(\"unit_price_snapshot\").notNull(),\n currency: text(\"currency\").notNull(),\n notes: text(\"notes\"),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n addedAt: timestamp(\"added_at\", { withTimezone: true }).defaultNow().notNull(),\n}, (table) => [\n index(\"idx_cart_line_items_cart_id\").on(table.cartId),\n]);\n",
|
|
11
|
+
"import { boolean, index, jsonb, pgTable, text, timestamp, uniqueIndex, uuid } from \"drizzle-orm/pg-core\";\nimport { organization } from \"../../auth/auth-schema\";\n\nexport const customers = pgTable(\"customers\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n organizationId: text(\"organization_id\").notNull().references(() => organization.id, { onDelete: \"cascade\" }),\n userId: text(\"user_id\").notNull(),\n email: text(\"email\"),\n phone: text(\"phone\"),\n firstName: text(\"first_name\"),\n lastName: text(\"last_name\"),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n createdAt: timestamp(\"created_at\", { withTimezone: true }).defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true }).defaultNow().notNull(),\n posOperatorPin: text(\"pos_operator_pin\"),\n}, (table) => ({\n orgIdx: index(\"idx_customers_org\").on(table.organizationId),\n orgUserIdUnique: uniqueIndex(\"customers_org_user_id_unique\").on(table.organizationId, table.userId),\n orgEmailUnique: uniqueIndex(\"customers_org_email_unique\").on(table.organizationId, table.email),\n}));\n\nexport const customerAddresses = pgTable(\"customer_addresses\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n customerId: uuid(\"customer_id\")\n .references(() => customers.id, { onDelete: \"cascade\" })\n .notNull(),\n type: text(\"type\", { enum: [\"shipping\", \"billing\"] }).notNull(),\n isDefault: boolean(\"is_default\").notNull().default(false),\n firstName: text(\"first_name\").notNull(),\n lastName: text(\"last_name\").notNull(),\n line1: text(\"line1\").notNull(),\n line2: text(\"line2\"),\n city: text(\"city\").notNull(),\n state: text(\"state\"),\n postalCode: text(\"postal_code\"),\n country: text(\"country\").notNull(),\n phone: text(\"phone\"),\n}, (table) => [\n index(\"idx_customer_addresses_customer_id\").on(table.customerId),\n]);\n\nexport const customerGroups = pgTable(\"customer_groups\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n organizationId: text(\"organization_id\").notNull().references(() => organization.id, { onDelete: \"cascade\" }),\n name: text(\"name\").notNull(),\n description: text(\"description\"),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n}, (table) => ({\n orgIdx: index(\"idx_customer_groups_org\").on(table.organizationId),\n orgNameUnique: uniqueIndex(\"customer_groups_org_name_unique\").on(table.organizationId, table.name),\n}));\n\nexport const customerGroupMembers = pgTable(\"customer_group_members\", {\n customerId: uuid(\"customer_id\")\n .references(() => customers.id, { onDelete: \"cascade\" })\n .notNull(),\n groupId: uuid(\"group_id\")\n .references(() => customerGroups.id, { onDelete: \"cascade\" })\n .notNull(),\n}, (table) => [\n index(\"idx_group_members_customer_id\").on(table.customerId),\n index(\"idx_group_members_group_id\").on(table.groupId),\n uniqueIndex(\"customer_group_members_customer_group_unique\").on(table.customerId, table.groupId),\n]);\n",
|
|
12
|
+
"import {\n pgTable,\n uuid,\n text,\n jsonb,\n integer,\n timestamp,\n index,\n} from \"drizzle-orm/pg-core\";\nimport { organization } from \"../../auth/auth-schema\";\n\nexport const commerceJobs = pgTable(\"commerce_jobs\", {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n organizationId: text(\"organization_id\")\n .notNull()\n .references(() => organization.id, { onDelete: \"cascade\" }),\n queue: text(\"queue\").notNull().default(\"default\"),\n taskSlug: text(\"task_slug\").notNull(),\n input: jsonb(\"input\").notNull().default(\"{}\"),\n output: jsonb(\"output\"),\n status: text(\"status\", {\n enum: [\"pending\", \"processing\", \"succeeded\", \"failed\"],\n })\n .notNull()\n .default(\"pending\"),\n attempts: integer(\"attempts\").notNull().default(0),\n maxAttempts: integer(\"max_attempts\").notNull().default(1),\n error: text(\"error\"),\n waitUntil: timestamp(\"wait_until\", { withTimezone: true }),\n concurrencyKey: text(\"concurrency_key\"),\n createdAt: timestamp(\"created_at\", { withTimezone: true })\n .notNull()\n .defaultNow(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true })\n .notNull()\n .defaultNow(),\n processingStartedAt: timestamp(\"processing_started_at\", {\n withTimezone: true,\n }),\n completedAt: timestamp(\"completed_at\", { withTimezone: true }),\n}, (table) => ({\n statusQueueIdx: index(\"idx_jobs_status_queue\").on(table.status, table.queue),\n taskSlugIdx: index(\"idx_jobs_task_slug\").on(table.taskSlug),\n waitUntilIdx: index(\"idx_jobs_wait_until\").on(table.waitUntil),\n orgIdx: index(\"idx_jobs_org\").on(table.organizationId),\n}));\n",
|
|
13
|
+
"import {\n boolean,\n index,\n integer,\n jsonb,\n pgTable,\n text,\n timestamp,\n uuid,\n} from \"drizzle-orm/pg-core\";\nimport { organization } from \"../../auth/auth-schema\";\n\nexport const webhookEndpoints = pgTable(\n \"webhook_endpoints\",\n {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n organizationId: text(\"organization_id\")\n .notNull()\n .references(() => organization.id, { onDelete: \"cascade\" }),\n url: text(\"url\").notNull(),\n secret: text(\"secret\").notNull(),\n events: jsonb(\"events\").$type<string[]>().notNull(),\n isActive: boolean(\"is_active\").notNull().default(true),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n },\n (table) => ({\n orgIdx: index(\"idx_webhook_endpoints_org\").on(table.organizationId),\n }),\n);\n\n/**\n * Tracks processed incoming webhook events for idempotency.\n * Prevents double-processing when Stripe (or other providers) retry delivery.\n */\nexport const processedWebhookEvents = pgTable(\"processed_webhook_events\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n eventId: text(\"event_id\").notNull().unique(),\n provider: text(\"provider\").notNull(), // \"stripe\", \"paypal\", etc.\n eventType: text(\"event_type\").notNull(),\n processedAt: timestamp(\"processed_at\", { withTimezone: true }).defaultNow().notNull(),\n});\n\nexport const webhookDeliveries = pgTable(\"webhook_deliveries\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n endpointId: uuid(\"endpoint_id\")\n .references(() => webhookEndpoints.id)\n .notNull(),\n eventName: text(\"event_name\").notNull(),\n payload: jsonb(\"payload\").notNull(),\n statusCode: integer(\"status_code\"),\n attemptCount: integer(\"attempt_count\").notNull().default(0),\n nextRetryAt: timestamp(\"next_retry_at\", { withTimezone: true }),\n deliveredAt: timestamp(\"delivered_at\", { withTimezone: true }),\n failedAt: timestamp(\"failed_at\", { withTimezone: true }),\n createdAt: timestamp(\"created_at\", { withTimezone: true }).defaultNow().notNull(),\n});\n",
|
|
14
|
+
"import {\n boolean,\n index,\n integer,\n jsonb,\n pgTable,\n text,\n timestamp,\n uniqueIndex,\n uuid,\n} from \"drizzle-orm/pg-core\";\nimport { organization } from \"../../auth/auth-schema\";\nimport { sellableEntities, variants } from \"../catalog/schema\";\n\nexport const warehouses = pgTable(\n \"warehouses\",\n {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n organizationId: text(\"organization_id\")\n .notNull()\n .references(() => organization.id, { onDelete: \"cascade\" }),\n name: text(\"name\").notNull(),\n code: text(\"code\").notNull(),\n address: jsonb(\"address\").$type<Record<string, unknown>>(),\n isActive: boolean(\"is_active\").notNull().default(true),\n priority: integer(\"priority\").notNull().default(0),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n },\n (table) => ({\n orgIdx: index(\"idx_warehouses_org\").on(table.organizationId),\n orgCodeUnique: uniqueIndex(\"warehouses_org_code_unique\").on(table.organizationId, table.code),\n }),\n);\n\nexport const inventoryLevels = pgTable(\n \"inventory_levels\",\n {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n entityId: uuid(\"entity_id\")\n .references(() => sellableEntities.id, { onDelete: \"cascade\" })\n .notNull(),\n variantId: uuid(\"variant_id\").references(() => variants.id, {\n onDelete: \"cascade\",\n }),\n warehouseId: uuid(\"warehouse_id\")\n .references(() => warehouses.id)\n .notNull(),\n quantityOnHand: integer(\"quantity_on_hand\").notNull().default(0),\n quantityReserved: integer(\"quantity_reserved\").notNull().default(0),\n quantityIncoming: integer(\"quantity_incoming\").notNull().default(0),\n unitCost: integer(\"unit_cost\"),\n reorderThreshold: integer(\"reorder_threshold\"),\n reorderQuantity: integer(\"reorder_quantity\"),\n version: integer(\"version\").notNull().default(0),\n lastRestockedAt: timestamp(\"last_restocked_at\", { withTimezone: true }),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true }).defaultNow().notNull(),\n },\n (table) => ({\n entityVariantWarehouseIdx: index(\"idx_inventory_entity_variant_warehouse\").on(\n table.entityId,\n table.variantId,\n table.warehouseId,\n ),\n }),\n);\n\nexport const inventoryMovements = pgTable(\"inventory_movements\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n entityId: uuid(\"entity_id\")\n .references(() => sellableEntities.id)\n .notNull(),\n variantId: uuid(\"variant_id\").references(() => variants.id),\n warehouseId: uuid(\"warehouse_id\")\n .references(() => warehouses.id)\n .notNull(),\n type: text(\"type\", {\n enum: [\n \"receipt\",\n \"sale\",\n \"return\",\n \"adjustment\",\n \"transfer\",\n \"reservation\",\n \"release\",\n \"fulfillment\",\n ],\n }).notNull(),\n quantity: integer(\"quantity\").notNull(),\n referenceType: text(\"reference_type\"),\n referenceId: text(\"reference_id\"),\n reason: text(\"reason\"),\n performedBy: text(\"performed_by\").notNull(),\n performedAt: timestamp(\"performed_at\", { withTimezone: true }).defaultNow().notNull(),\n});\n",
|
|
15
|
+
"import { index, integer, jsonb, pgTable, text, timestamp, uuid } from \"drizzle-orm/pg-core\";\nimport { organization } from \"../../auth/auth-schema\";\nimport { sellableEntities, variants } from \"../catalog/schema\";\n\nexport const prices = pgTable(\n \"prices\",\n {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n organizationId: text(\"organization_id\")\n .notNull()\n .references(() => organization.id, { onDelete: \"cascade\" }),\n entityId: uuid(\"entity_id\")\n .references(() => sellableEntities.id, { onDelete: \"cascade\" })\n .notNull(),\n variantId: uuid(\"variant_id\").references(() => variants.id, { onDelete: \"cascade\" }),\n currency: text(\"currency\").notNull(),\n amount: integer(\"amount\").notNull(),\n customerGroupId: text(\"customer_group_id\"),\n minQuantity: integer(\"min_quantity\"),\n maxQuantity: integer(\"max_quantity\"),\n validFrom: timestamp(\"valid_from\", { withTimezone: true }),\n validUntil: timestamp(\"valid_until\", { withTimezone: true }),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n createdAt: timestamp(\"created_at\", { withTimezone: true }).defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true }).defaultNow().notNull(),\n },\n (table) => ({\n entityVariantCurrencyIdx: index(\"idx_prices_entity_variant_currency\").on(\n table.entityId,\n table.variantId,\n table.currency,\n ),\n customerGroupIdx: index(\"idx_prices_customer_group\").on(table.customerGroupId),\n quantityIdx: index(\"idx_prices_quantity\").on(table.minQuantity, table.maxQuantity),\n validityIdx: index(\"idx_prices_validity\").on(table.validFrom, table.validUntil),\n orgIdx: index(\"idx_prices_org\").on(table.organizationId),\n }),\n);\n\nexport const priceModifiers = pgTable(\n \"price_modifiers\",\n {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n organizationId: text(\"organization_id\")\n .notNull()\n .references(() => organization.id, { onDelete: \"cascade\" }),\n name: text(\"name\").notNull(),\n type: text(\"type\", {\n enum: [\"percentage_discount\", \"fixed_discount\", \"markup\", \"override\"],\n }).notNull(),\n value: integer(\"value\").notNull(),\n priority: integer(\"priority\").notNull().default(100),\n entityId: uuid(\"entity_id\").references(() => sellableEntities.id, { onDelete: \"cascade\" }),\n variantId: uuid(\"variant_id\").references(() => variants.id, { onDelete: \"cascade\" }),\n customerGroupId: text(\"customer_group_id\"),\n currency: text(\"currency\").default(\"USD\"),\n minQuantity: integer(\"min_quantity\"),\n maxQuantity: integer(\"max_quantity\"),\n conditions: jsonb(\"conditions\").$type<Record<string, unknown>>().default({}),\n validFrom: timestamp(\"valid_from\", { withTimezone: true }),\n validUntil: timestamp(\"valid_until\", { withTimezone: true }),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n createdAt: timestamp(\"created_at\", { withTimezone: true }).defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true }).defaultNow().notNull(),\n },\n (table) => ({\n entityVariantIdx: index(\"idx_price_modifiers_entity_variant\").on(table.entityId, table.variantId),\n priorityIdx: index(\"idx_price_modifiers_priority\").on(table.priority),\n orgIdx: index(\"idx_price_modifiers_org\").on(table.organizationId),\n }),\n);\n",
|
|
16
|
+
"import { boolean, index, integer, jsonb, pgTable, text, timestamp, uniqueIndex, uuid } from \"drizzle-orm/pg-core\";\nimport { organization } from \"../../auth/auth-schema\";\n\nexport const promotions = pgTable(\n \"promotions\",\n {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n organizationId: text(\"organization_id\")\n .notNull()\n .references(() => organization.id, { onDelete: \"cascade\" }),\n code: text(\"code\"),\n name: text(\"name\").notNull(),\n type: text(\"type\", {\n enum: [\n \"percentage_off_order\",\n \"fixed_off_order\",\n \"percentage_off_item\",\n \"fixed_off_item\",\n \"free_shipping\",\n \"buy_x_get_y\",\n ],\n }).notNull(),\n value: integer(\"value\").notNull().default(0),\n buyQuantity: integer(\"buy_quantity\"),\n getQuantity: integer(\"get_quantity\"),\n isAutomatic: boolean(\"is_automatic\").notNull().default(false),\n isActive: boolean(\"is_active\").notNull().default(true),\n priority: integer(\"priority\").notNull().default(100),\n conditions: jsonb(\"conditions\").$type<Record<string, unknown>>().default({}),\n usageLimitTotal: integer(\"usage_limit_total\"),\n usageLimitPerCustomer: integer(\"usage_limit_per_customer\"),\n validFrom: timestamp(\"valid_from\", { withTimezone: true }),\n validUntil: timestamp(\"valid_until\", { withTimezone: true }),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n createdAt: timestamp(\"created_at\", { withTimezone: true }).defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true }).defaultNow().notNull(),\n },\n (table) => ({\n codeIdx: index(\"idx_promotions_code\").on(table.code),\n activePriorityIdx: index(\"idx_promotions_active_priority\").on(table.isActive, table.priority),\n validityIdx: index(\"idx_promotions_validity\").on(table.validFrom, table.validUntil),\n orgIdx: index(\"idx_promotions_org\").on(table.organizationId),\n orgCodeUnique: uniqueIndex(\"promotions_org_code_unique\").on(table.organizationId, table.code),\n }),\n);\n\nexport const promotionUsages = pgTable(\n \"promotion_usages\",\n {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n promotionId: uuid(\"promotion_id\")\n .references(() => promotions.id, { onDelete: \"cascade\" })\n .notNull(),\n customerId: uuid(\"customer_id\"),\n orderId: uuid(\"order_id\"),\n usedAt: timestamp(\"used_at\", { withTimezone: true }).defaultNow().notNull(),\n },\n (table) => ({\n promotionIdx: index(\"idx_promotion_usage_promotion\").on(table.promotionId),\n customerIdx: index(\"idx_promotion_usage_customer\").on(table.customerId),\n }),\n);\n",
|
|
17
|
+
"import {\n integer,\n jsonb,\n pgTable,\n text,\n timestamp,\n uuid,\n boolean,\n} from \"drizzle-orm/pg-core\";\nimport { orders, orderLineItems } from \"../orders/schema\";\nimport { customers } from \"../customers/schema\";\n\n/**\n * Fulfillment Records Table\n *\n * Tracks physical shipments, digital deliveries, and access grants.\n * Each fulfillment can be associated with one or more order line items.\n */\nexport const fulfillmentRecords = pgTable(\"fulfillment_records\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n orderId: uuid(\"order_id\")\n .references(() => orders.id, { onDelete: \"cascade\" })\n .notNull(),\n customerId: uuid(\"customer_id\").references(() => customers.id),\n\n // Fulfillment type: \"physical\", \"digital\", \"access_grant\"\n type: text(\"type\").notNull(),\n\n // Status: \"pending\", \"processing\", \"shipped\", \"delivered\", \"cancelled\", \"failed\"\n status: text(\"status\").notNull().default(\"pending\"),\n\n // Physical shipment fields\n carrier: text(\"carrier\"),\n trackingNumber: text(\"tracking_number\"),\n trackingUrl: text(\"tracking_url\"),\n estimatedDelivery: timestamp(\"estimated_delivery\", { withTimezone: true }),\n shippedAt: timestamp(\"shipped_at\", { withTimezone: true }),\n deliveredAt: timestamp(\"delivered_at\", { withTimezone: true }),\n\n // Digital delivery fields\n downloadUrl: text(\"download_url\"),\n downloadExpiresAt: timestamp(\"download_expires_at\", { withTimezone: true }),\n maxDownloads: integer(\"max_downloads\"),\n downloadCount: integer(\"download_count\").notNull().default(0),\n\n // Access grant fields (e.g., course access, membership)\n entityType: text(\"entity_type\"),\n entityId: uuid(\"entity_id\"),\n grantedAt: timestamp(\"granted_at\", { withTimezone: true }),\n expiresAt: timestamp(\"expires_at\", { withTimezone: true }),\n isActive: boolean(\"is_active\").notNull().default(true),\n\n // Metadata for extensibility\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n\n // Timestamps\n createdAt: timestamp(\"created_at\", { withTimezone: true })\n .defaultNow()\n .notNull(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true })\n .defaultNow()\n .notNull(),\n});\n\n/**\n * Fulfillment Line Items Junction Table\n *\n * Links fulfillment records to order line items (many-to-many).\n * Allows partial fulfillments where only some items from an order are fulfilled together.\n */\nexport const fulfillmentLineItems = pgTable(\"fulfillment_line_items\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n fulfillmentId: uuid(\"fulfillment_id\")\n .references(() => fulfillmentRecords.id, { onDelete: \"cascade\" })\n .notNull(),\n orderLineItemId: uuid(\"order_line_item_id\")\n .references(() => orderLineItems.id, { onDelete: \"cascade\" })\n .notNull(),\n quantity: integer(\"quantity\").notNull(),\n});\n\n/**\n * Fulfillment Events Table\n *\n * Audit trail of fulfillment status changes and events.\n */\nexport const fulfillmentEvents = pgTable(\"fulfillment_events\", {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n fulfillmentId: uuid(\"fulfillment_id\")\n .references(() => fulfillmentRecords.id, { onDelete: \"cascade\" })\n .notNull(),\n eventType: text(\"event_type\").notNull(), // \"created\", \"shipped\", \"delivered\", \"cancelled\", \"download\", etc.\n fromStatus: text(\"from_status\"),\n toStatus: text(\"to_status\"),\n description: text(\"description\"),\n actorId: text(\"actor_id\"), // User/system that triggered the event\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n occurredAt: timestamp(\"occurred_at\", { withTimezone: true })\n .defaultNow()\n .notNull(),\n});\n",
|
|
18
|
+
"import { index, integer, jsonb, pgTable, text, timestamp, uuid } from \"drizzle-orm/pg-core\";\nimport { organization } from \"../../auth/auth-schema\";\nimport { sellableEntities, variants } from \"../catalog/schema\";\n\nexport const mediaAssets = pgTable(\n \"media_assets\",\n {\n id: uuid(\"id\").defaultRandom().primaryKey(),\n organizationId: text(\"organization_id\")\n .notNull()\n .references(() => organization.id, { onDelete: \"cascade\" }),\n storageKey: text(\"storage_key\").notNull(),\n filename: text(\"filename\").notNull(),\n contentType: text(\"content_type\").notNull(),\n size: integer(\"size\").notNull(),\n width: integer(\"width\"),\n height: integer(\"height\"),\n alt: text(\"alt\"),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>().default({}),\n uploadedAt: timestamp(\"uploaded_at\", { withTimezone: true }).defaultNow().notNull(),\n },\n (table) => ({\n orgIdx: index(\"idx_media_assets_org\").on(table.organizationId),\n }),\n);\n\nexport const entityMedia = pgTable(\"entity_media\", {\n entityId: uuid(\"entity_id\")\n .references(() => sellableEntities.id, { onDelete: \"cascade\" })\n .notNull(),\n variantId: uuid(\"variant_id\").references(() => variants.id, {\n onDelete: \"cascade\",\n }),\n mediaAssetId: uuid(\"media_asset_id\")\n .references(() => mediaAssets.id, { onDelete: \"cascade\" })\n .notNull(),\n role: text(\"role\", {\n enum: [\"primary\", \"gallery\", \"thumbnail\", \"video\", \"document\"],\n }).notNull(),\n sortOrder: integer(\"sort_order\").notNull().default(0),\n});\n",
|
|
19
|
+
"import {\n pgTable,\n uuid,\n text,\n jsonb,\n timestamp,\n index,\n} from \"drizzle-orm/pg-core\";\nimport { organization } from \"../../auth/auth-schema\";\n\nexport const auditLog = pgTable(\n \"commerce_audit_log\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n organizationId: text(\"organization_id\")\n .notNull()\n .references(() => organization.id, { onDelete: \"cascade\" }),\n entityType: text(\"entity_type\").notNull(),\n entityId: text(\"entity_id\").notNull(),\n event: text(\"event\").notNull(),\n payload: jsonb(\"payload\").notNull().default(\"{}\"),\n actorId: text(\"actor_id\"),\n actorType: text(\"actor_type\"),\n requestId: text(\"request_id\"),\n createdAt: timestamp(\"created_at\", { withTimezone: true })\n .notNull()\n .defaultNow(),\n },\n (table) => ({\n entityIdx: index(\"idx_audit_entity\").on(table.entityType, table.entityId),\n orgIdx: index(\"idx_audit_org\").on(table.organizationId),\n }),\n);\n",
|
|
20
|
+
"import { eq, and, sql } from \"drizzle-orm\";\nimport type { DrizzleDatabase } from \"../database/drizzle-db\";\nimport type { Logger, ServiceContainer } from \"../hooks/types\";\nimport type { TaskDefinition } from \"./types\";\nimport { commerceJobs } from \"./schema\";\n\nexport interface RunPendingJobsArgs {\n db: DrizzleDatabase;\n tasks: Map<string, TaskDefinition>;\n queue?: string;\n limit?: number;\n logger: Logger;\n services: ServiceContainer;\n}\n\n/**\n * Claims and processes pending jobs from the `commerce_jobs` table.\n *\n * Uses `FOR UPDATE SKIP LOCKED` to allow multiple runners to process\n * jobs in parallel without conflicts. Each runner claims a batch,\n * marks them as processing, then executes handlers outside the\n * claim transaction.\n */\nexport async function runPendingJobs(\n args: RunPendingJobsArgs,\n): Promise<{ processed: number; failed: number }> {\n const {\n db,\n tasks,\n queue = \"default\",\n limit = 10,\n logger,\n services,\n } = args;\n\n let processed = 0;\n let failed = 0;\n\n // Phase 1: Claim jobs atomically\n const claimed = await db.transaction(async (tx) => {\n const pending = await tx\n .select()\n .from(commerceJobs)\n .where(\n and(\n eq(commerceJobs.status, \"pending\"),\n eq(commerceJobs.queue, queue),\n sql`(${commerceJobs.waitUntil} IS NULL OR ${commerceJobs.waitUntil} <= now())`,\n ),\n )\n .orderBy(commerceJobs.createdAt)\n .limit(limit)\n .for(\"update\", { skipLocked: true });\n\n for (const job of pending) {\n await tx\n .update(commerceJobs)\n .set({\n status: \"processing\",\n processingStartedAt: new Date(),\n updatedAt: new Date(),\n })\n .where(eq(commerceJobs.id, job.id));\n }\n\n return pending;\n });\n\n // Phase 2: Execute each claimed job outside the claim transaction\n for (const job of claimed) {\n const task = tasks.get(job.taskSlug);\n\n if (!task) {\n logger.warn(\"Unknown task slug — job marked as failed. Register the task handler in config.jobs.tasks.\", {\n taskSlug: job.taskSlug,\n jobId: job.id,\n });\n await db\n .update(commerceJobs)\n .set({\n status: \"failed\",\n error: `Unknown task slug: ${job.taskSlug}`,\n updatedAt: new Date(),\n completedAt: new Date(),\n })\n .where(eq(commerceJobs.id, job.id));\n failed++;\n continue;\n }\n\n try {\n const result = await task.handler({\n input: job.input as Record<string, unknown>,\n ctx: { logger, db, services },\n });\n\n await db\n .update(commerceJobs)\n .set({\n status: \"succeeded\",\n output: result.output,\n attempts: job.attempts + 1,\n updatedAt: new Date(),\n completedAt: new Date(),\n })\n .where(eq(commerceJobs.id, job.id));\n\n processed++;\n } catch (err) {\n logger.error(\"Job handler failed\", {\n taskSlug: job.taskSlug,\n jobId: job.id,\n error: err instanceof Error ? err.message : String(err),\n });\n const attempts = job.attempts + 1;\n const maxAttempts = job.maxAttempts;\n\n if (attempts >= maxAttempts) {\n await db\n .update(commerceJobs)\n .set({\n status: \"failed\",\n error: err instanceof Error ? err.message : String(err),\n attempts,\n updatedAt: new Date(),\n completedAt: new Date(),\n })\n .where(eq(commerceJobs.id, job.id));\n failed++;\n } else {\n // Compute backoff delay\n const retries = task.retries;\n const delay =\n retries?.backoff?.type === \"exponential\"\n ? retries.backoff.delay * Math.pow(2, attempts - 1)\n : (retries?.backoff?.delay ?? 1000);\n\n await db\n .update(commerceJobs)\n .set({\n status: \"pending\",\n error: err instanceof Error ? err.message : String(err),\n attempts,\n waitUntil: new Date(Date.now() + delay),\n updatedAt: new Date(),\n })\n .where(eq(commerceJobs.id, job.id));\n }\n }\n }\n\n return { processed, failed };\n}\n",
|
|
21
|
+
"/**\n * Combined schema barrel for Drizzle.\n *\n * Single source of truth for all core table definitions. Both drizzle-kit\n * (via drizzle.config.ts) and the TypeScript type system consume this file.\n *\n * Drizzle-kit resolves re-exports, so pointing the config schema option\n * at this one file discovers every core table. Plugin schemas live in\n * their own packages and are referenced via glob patterns.\n */\n\n// Auth (Better Auth generated tables)\nexport * from \"../../auth/auth-schema\";\n\n// Catalog module\nexport * from \"../../modules/catalog/schema\";\n\n// Inventory module\nexport * from \"../../modules/inventory/schema\";\n\n// Cart module\nexport * from \"../../modules/cart/schema\";\n\n// Orders module\nexport * from \"../../modules/orders/schema\";\n\n// Customers module\nexport * from \"../../modules/customers/schema\";\n\n// Pricing module\nexport * from \"../../modules/pricing/schema\";\n\n// Promotions module\nexport * from \"../../modules/promotions/schema\";\n\n// Media module\nexport * from \"../../modules/media/schema\";\n\n// Webhooks module\nexport * from \"../../modules/webhooks/schema\";\n\n// Fulfillment module\nexport * from \"../../modules/fulfillment/schema\";\n\n// Jobs (kernel)\nexport * from \"../jobs/schema\";\n\n// Audit module\nexport * from \"../../modules/audit/schema\";\n",
|
|
22
|
+
"/**\n * Programmatic database schema management.\n *\n * For npm consumers who don't have access to the raw .ts schema files,\n * this module provides:\n *\n * 1. `getSchemaFiles()` — returns schema module paths for use in drizzle.config.ts\n * 2. `getSchema()` — returns the combined Drizzle schema object\n * 3. `pushSchema()` — programmatic push (creates tables if not exist)\n *\n * Usage in consumer's drizzle.config.ts:\n *\n * import { getSchema } from \"@unifiedcommerce/core\";\n * import { defineConfig } from \"drizzle-kit\";\n *\n * export default defineConfig({\n * dialect: \"postgresql\",\n * schema: getSchema(),\n * dbCredentials: { url: process.env.DATABASE_URL! },\n * });\n */\n\nimport type { CommerceConfig } from \"../../config/types\";\nimport * as schema from \"./schema\";\n\n/**\n * Returns the combined Drizzle schema object with all table definitions.\n * Use this in your own drizzle.config.ts or for programmatic schema inspection.\n */\nexport function getSchema() {\n return schema;\n}\n\n/**\n * Returns core schema merged with all plugin schemas from `config.customSchemas[]`.\n * Throws if a plugin table name collides with a core table name.\n */\nexport function buildSchema(config?: CommerceConfig): Record<string, unknown> {\n const merged: Record<string, unknown> = { ...schema };\n\n if (!config?.customSchemas?.length) return merged;\n\n const coreKeys = new Set(Object.keys(schema));\n\n for (const pluginSchema of config.customSchemas) {\n for (const [key, value] of Object.entries(pluginSchema)) {\n if (coreKeys.has(key)) {\n throw new Error(\n `Plugin schema name collision: \"${key}\" already exists in core schema`,\n );\n }\n if (key in merged) {\n throw new Error(\n `Plugin schema name collision: \"${key}\" is defined by multiple plugins`,\n );\n }\n merged[key] = value;\n }\n }\n\n return merged;\n}\n\n/**\n * Returns a list of all schema table names defined by the commerce engine.\n */\nexport function getTableNames(): string[] {\n return Object.entries(schema)\n .filter(\n ([_, value]) =>\n value != null &&\n typeof value === \"object\" &&\n \"getSQL\" in (value as object),\n )\n .map(([key]) => key);\n}\n",
|
|
23
|
+
"/**\n * PGlite-backed test adapter for real PostgreSQL behavior in tests.\n *\n * Creates an in-memory PGlite (WASM PostgreSQL) instance, pushes the\n * core Drizzle schema programmatically via drizzle-kit/api, and provides\n * a cleanup function to reset data between tests.\n *\n * Benefits over in-memory repository doubles:\n * - Real SQL execution (Drizzle query generation)\n * - PostgreSQL type coercion and constraint enforcement\n * - Real transaction rollback semantics\n * - Production parity for query edge cases\n */\n\nimport { PGlite } from \"@electric-sql/pglite\";\nimport { drizzle } from \"drizzle-orm/pglite\";\nimport { sql } from \"drizzle-orm\";\nimport { createRequire } from \"node:module\";\nimport type { PgDatabase, PgQueryResultHKT } from \"drizzle-orm/pg-core\";\nimport type { DatabaseAdapter } from \"../kernel/database/adapter\";\nimport { getSchema } from \"../kernel/database/migrate\";\nimport { ensureDefaultOrg } from \"../auth/org\";\n\n// Single barrel import --- includes all core modules + auth tables\nimport * as fullSchema from \"../kernel/database/schema\";\nimport type { DrizzleDatabase } from \"../kernel/database/drizzle-db\";\n\n// drizzle-kit/api uses CJS internally; createRequire provides ESM compat.\nconst require = createRequire(import.meta.url);\n\n/**\n * Pushes the core Drizzle schema to the database using drizzle-kit/api.\n *\n * Replaces the previous approach of reading migration SQL files. Instead,\n * drizzle-kit introspects the live database via information_schema, diffs\n * against the pgTable definitions, and generates the minimal DDL needed.\n *\n * For a fresh PGlite instance, all statements are CREATE TABLE + CREATE INDEX.\n */\nasync function pushCoreSchema(db: PgDatabase<PgQueryResultHKT>): Promise<void> {\n const coreSchema = getSchema();\n const drizzleKit = require(\"drizzle-kit/api\") as {\n pushSchema(\n imports: Record<string, unknown>,\n drizzleInstance: PgDatabase<PgQueryResultHKT>,\n ): Promise<{ apply: () => Promise<void> }>;\n };\n const { apply } = await drizzleKit.pushSchema(coreSchema, db);\n await apply();\n}\n\n/**\n * Creates a PGlite-backed database adapter for testing.\n *\n * Each call creates a new isolated PGlite instance with its own\n * in-memory database. Core schema is pushed once during initialization.\n *\n * @returns A promise resolving to an object containing:\n * - adapter: The DatabaseAdapter for use with createKernel\n * - db: The Drizzle ORM instance for direct queries\n * - cleanup: Function to truncate all tables (call between tests)\n */\nexport async function createPGliteTestAdapter(): Promise<{\n adapter: DatabaseAdapter;\n db: DrizzleDatabase;\n cleanup: () => Promise<void>;\n}> {\n // Create in-memory PGlite instance\n const pg = new PGlite();\n\n // Wrap with Drizzle ORM first (pushSchema needs the Drizzle instance)\n const db = drizzle(pg, { schema: fullSchema });\n\n // Push core schema via drizzle-kit/api (no migration files needed)\n await pushCoreSchema(db as unknown as PgDatabase<PgQueryResultHKT>);\n\n // Ensure the default organization exists for all tests\n await ensureDefaultOrg(db);\n\n /**\n * PGlite-compatible transaction wrapper.\n *\n * Drizzle's transaction() method can hang with PGlite due to how\n * the adapter manages transaction state. This implementation uses\n * manual BEGIN/COMMIT control which works more reliably.\n */\n async function transaction<T>(fn: (tx: unknown) => Promise<T>): Promise<T> {\n await pg.exec(\"BEGIN\");\n try {\n const result = await fn(db);\n await pg.exec(\"COMMIT\");\n return result;\n } catch (error) {\n await pg.exec(\"ROLLBACK\");\n throw error;\n }\n }\n\n const adapter: DatabaseAdapter = {\n provider: \"postgresql\",\n db,\n async transaction<T>(fn: (tx: unknown) => Promise<T>): Promise<T> {\n return transaction(fn);\n },\n };\n\n /**\n * Cleanup function to reset data between tests.\n * Truncates all tables in reverse dependency order with CASCADE.\n */\n async function cleanup(): Promise<void> {\n await db.execute(sql`\n DO $$ DECLARE\n r RECORD;\n BEGIN\n FOR r IN (\n SELECT tablename FROM pg_tables\n WHERE schemaname = 'public'\n ) LOOP\n EXECUTE 'TRUNCATE TABLE ' || quote_ident(r.tablename) || ' CASCADE';\n END LOOP;\n END $$;\n `);\n // Re-insert default org after truncation (CASCADE wipes it)\n await ensureDefaultOrg(db);\n }\n\n return { adapter, db, cleanup };\n}\n",
|
|
24
|
+
"import type { CommerceConfig } from \"./types\";\n\nexport const defaultConfig: Partial<CommerceConfig> = {\n version: \"0.0.1\",\n auth: {\n requireEmailVerification: true,\n sessionDuration: 60 * 60 * 24 * 7,\n twoFactor: { enabled: false },\n apiKeys: { enabled: false },\n posPin: { enabled: false },\n roles: {\n owner: { permissions: [\"*:*\"] },\n admin: { permissions: [\"*:*\"] },\n manager: {\n permissions: [\n \"catalog:create\",\n \"catalog:update\",\n \"catalog:delete\",\n \"catalog:read\",\n \"inventory:read\",\n \"inventory:adjust\",\n \"orders:read\",\n \"orders:update\",\n \"cart:create\",\n \"cart:update\",\n \"customers:read:self\",\n \"customers:update:self\",\n ],\n },\n customer: {\n permissions: [\n \"catalog:read\",\n \"cart:create\",\n \"cart:read\",\n \"cart:update\",\n \"orders:create\",\n \"orders:read:own\",\n \"customers:read:self\",\n \"customers:update:self\",\n ],\n },\n },\n customerPermissions: [\n \"catalog:read\",\n \"cart:create\",\n \"cart:read\",\n \"cart:update\",\n \"orders:create\",\n \"orders:read:own\",\n \"customers:read:self\",\n \"customers:update:self\",\n ],\n },\n cart: {\n ttlMinutes: 60 * 24 * 7,\n hooks: {},\n },\n checkout: {\n hooks: {\n beforeCreate: [],\n afterCreate: [],\n },\n },\n orders: {\n hooks: {\n beforeCreate: [],\n afterCreate: [],\n beforeStatusChange: [],\n afterStatusChange: [],\n beforeDelete: [],\n },\n },\n inventory: {\n hooks: {\n afterAdjust: [],\n },\n },\n mcp: {\n enabled: true,\n capabilities: [\"catalog:read\", \"orders:read\", \"inventory:read\"],\n },\n};\n",
|
|
25
|
+
"import type { Hono } from \"hono\";\nimport type { OpenAPIHono, RouteConfig } from \"@hono/zod-openapi\";\nimport type { PgDatabase, PgQueryResultHKT } from \"drizzle-orm/pg-core\";\nimport type {\n CommerceConfig,\n CommercePlugin,\n MCPTool,\n} from \"../../config/types\";\n\n// ─── Plugin Logger ────────────────────────────────────────────────────\n\nexport interface PluginLogger {\n info(message: string, data?: unknown): void;\n warn(message: string, data?: unknown): void;\n error(message: string, data?: unknown): void;\n}\n\n// ─── Plugin Registration Types ────────────────────────────────────────\n\n/**\n * Plugin route registration. Supports two modes:\n *\n * 1. Legacy: { method, path, handler } — works, but invisible to OpenAPI spec.\n * 2. OpenAPI: { openapi, handler } — validated by Zod, appears in /api/doc.\n *\n * Use mode 2 for any route that accepts a request body or returns structured data.\n * Mode 1 is acceptable for simple routes (health checks, redirects, file serving).\n */\nexport type PluginRouteRegistration =\n | { method: string; path: string; handler: (...args: unknown[]) => unknown }\n | { openapi: RouteConfig; handler: (...args: unknown[]) => unknown };\n\nexport interface PluginHookRegistration {\n key: string;\n handler: (...args: unknown[]) => unknown;\n}\n\n// ─── Plugin Context (available to routes/mcpTools at boot time) ───────\n\nexport interface PluginContext {\n config: CommerceConfig;\n services: Record<string, unknown>;\n database: {\n /** Drizzle database instance — use for queries, inserts, updates, deletes */\n db: PgDatabase<PgQueryResultHKT, Record<string, unknown>>;\n transaction<T>(fn: (tx: PgDatabase<PgQueryResultHKT, Record<string, unknown>>) => Promise<T>): Promise<T>;\n };\n logger: PluginLogger;\n}\n\n// ─── Plugin Manifest (input to defineCommercePlugin) ──────────────────\n\n/**\n * Permission scope declared by a plugin.\n * Collected at boot time and available via GET /api/admin/permissions.\n */\nexport interface PluginPermission {\n /** Permission scope string, e.g., \"wishlist:write\", \"marketplace:admin\" */\n scope: string;\n /** Human-readable description for admin UIs */\n description: string;\n}\n\nexport interface CommercePluginManifest {\n id: string;\n version: string;\n /**\n * IDs of plugins that must be registered before this one.\n * If any required plugin is missing at registration time,\n * defineCommercePlugin will throw with a clear message.\n */\n requires?: string[];\n /**\n * Permission scopes this plugin introduces.\n * Used by admin UIs to build role editors, and validated at boot time\n * against .permission() calls in routes.\n */\n permissions?: PluginPermission[];\n /**\n * Returns Drizzle `pgTable` objects that this plugin needs.\n * These are collected into `config.customSchemas[]` and merged with core\n * schema by `buildSchema(config)`. Each key becomes a named export in the\n * merged schema; names must not collide with core table exports.\n */\n schema?: () => Record<string, unknown>;\n hooks?: () => PluginHookRegistration[];\n routes?: (ctx: PluginContext) => PluginRouteRegistration[];\n mcpTools?: (ctx: PluginContext) => MCPTool[];\n analyticsModels?: () => unknown[];\n}\n\n// ─── Plugin Dependency Tracking ──────────────────────────────────────\n// Accumulates plugin IDs as they register during defineConfig().\n// Reset at the start of each defineConfig() call.\nexport const _registeredPlugins = new Set<string>();\n\n/** @internal — called by defineConfig() before applying plugins */\nexport function _resetRegisteredPlugins(): void {\n _registeredPlugins.clear();\n}\n\n/**\n * Converts a plugin manifest into a config transform function.\n *\n * - `schema` → pushed into `config.customSchemas`\n * - `hooks` → merged into `config.hooks` flat map\n * - `routes` → chained onto `config.routes` (evaluated at boot with kernel)\n * - `mcpTools` → chained onto `config.mcpTools` (evaluated at boot with kernel)\n * - `analyticsModels` → pushed into `config.analytics.models`\n */\nexport function defineCommercePlugin(\n manifest: CommercePluginManifest,\n): CommercePlugin {\n return (config: CommerceConfig): CommerceConfig => {\n // ── Dependency check ───────────────────────────────────────────\n // In test/development, warn instead of throwing so plugins can be\n // tested in isolation via createPluginTestApp() without installing\n // all dependencies. In production, this is a hard error.\n if (manifest.requires) {\n for (const dep of manifest.requires) {\n if (!_registeredPlugins.has(dep)) {\n const msg = `Plugin \"${manifest.id}\" requires \"${dep}\" to be installed before it. Add ${dep}Plugin() before ${manifest.id}Plugin() in your config.plugins array.`;\n if (process.env.NODE_ENV === \"production\") {\n throw new Error(msg);\n }\n // Non-production: log warning but continue (allows isolated testing)\n console.warn(`[plugin:${manifest.id}] WARNING: ${msg}`);\n }\n }\n }\n _registeredPlugins.add(manifest.id);\n let result = { ...config };\n\n // 1. Schema — push into customSchemas for kernel to register\n if (manifest.schema) {\n const schemas = manifest.schema();\n result = {\n ...result,\n customSchemas: [...(result.customSchemas ?? []), schemas],\n };\n }\n\n // 2. Hooks — merge into flat hooks map (kernel registers at boot)\n if (manifest.hooks) {\n const registrations = manifest.hooks();\n const hookMap: Record<string, Array<(...args: unknown[]) => unknown>> = {\n ...(result.hooks ?? {}),\n };\n for (const reg of registrations) {\n hookMap[reg.key] = [...(hookMap[reg.key] ?? []), reg.handler];\n }\n result = { ...result, hooks: hookMap };\n }\n\n // 3. Routes — chain onto config.routes (deferred: needs kernel at boot)\n if (manifest.routes) {\n const existingRoutes = result.routes;\n const pluginRoutes = manifest.routes;\n result = {\n ...result,\n routes: (app: Hono, kernel: unknown) => {\n existingRoutes?.(app, kernel);\n const k = kernel as {\n config: CommerceConfig;\n services: Record<string, unknown>;\n database: PluginContext[\"database\"];\n logger: PluginLogger;\n };\n const regs = pluginRoutes({\n config: k.config,\n services: k.services,\n database: k.database,\n logger: k.logger,\n });\n for (const route of regs) {\n // ── Error boundary: wrap handler with plugin context ──\n const originalHandler = route.handler;\n const wrappedHandler = async (...args: unknown[]) => {\n try {\n return await originalHandler(...args);\n } catch (err) {\n // Try to extract logger from Hono context\n const c = args[0] as Record<string, unknown>;\n const logger = (c?.get as Function)?.(\"logger\") as { error: Function } | undefined;\n logger?.error?.(\n { err, plugin: manifest.id },\n `[plugin:${manifest.id}] route handler error`,\n );\n throw err; // re-throw so global handler still catches\n }\n };\n\n if (\"openapi\" in route) {\n // OpenAPI route: validated by Zod, appears in /api/doc\n // Hono type interop — OpenAPIHono.openapi() expects strict RouteConfig+Handler\n // generics that can't be statically resolved for dynamic plugin routes.\n // @ts-expect-error -- dynamic plugin routes cannot satisfy Hono's strict handler generics\n (app as unknown as OpenAPIHono).openapi(route.openapi, wrappedHandler);\n } else {\n // Legacy route: raw handler, invisible to OpenAPI spec\n const method = route.method.toLowerCase();\n const router = app as unknown as Record<string, (path: string, handler: unknown) => void>;\n if (method in router) {\n router[method]!(route.path, wrappedHandler);\n }\n }\n }\n },\n };\n }\n\n // 4. MCP Tools — chain onto config.mcpTools (deferred: needs kernel)\n if (manifest.mcpTools) {\n const existingMcpTools = result.mcpTools;\n const pluginMcpTools = manifest.mcpTools;\n result = {\n ...result,\n mcpTools: (kernel: unknown) => {\n const existing = existingMcpTools?.(kernel) ?? [];\n const k = kernel as {\n config: CommerceConfig;\n services: Record<string, unknown>;\n database: PluginContext[\"database\"];\n logger: PluginLogger;\n };\n return [\n ...existing,\n ...pluginMcpTools({\n config: k.config,\n services: k.services,\n database: k.database,\n logger: k.logger,\n }),\n ];\n },\n };\n }\n\n // 5. Analytics models — push into config.analytics.models\n if (manifest.analyticsModels) {\n const models = manifest.analyticsModels();\n result = {\n ...result,\n analytics: {\n ...result.analytics,\n models: [...(result.analytics?.models ?? []), ...models],\n },\n };\n }\n\n return result;\n };\n}\n",
|
|
26
|
+
"import { defaultConfig } from \"./defaults\";\nimport type { CommerceConfig, DefineConfigInput } from \"./types\";\nimport { _resetRegisteredPlugins } from \"../kernel/plugin/manifest\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction merge<T extends object>(base: T, next: Partial<T>): T {\n const output: Record<string, unknown> = {\n ...(base as Record<string, unknown>),\n };\n for (const [key, value] of Object.entries(next as Record<string, unknown>)) {\n if (value === undefined) continue;\n const baseValue = output[key];\n if (\n isRecord(value) &&\n isRecord(baseValue)\n ) {\n output[key] = merge(baseValue, value);\n } else {\n output[key] = value;\n }\n }\n return output as T;\n}\n\n/**\n * Builds the final CommerceConfig by:\n * 1. Merging user input with defaults\n * 2. Applying all plugins (each is a config transform function)\n * 3. Freezing the result to prevent runtime mutation\n */\nexport async function defineConfig(\n input: DefineConfigInput,\n): Promise<CommerceConfig> {\n let config = merge(defaultConfig as CommerceConfig, input);\n\n // Merge top-level `schema` into `customSchemas` before plugins run\n if (config.schema?.length) {\n config = {\n ...config,\n customSchemas: [...(config.customSchemas ?? []), ...config.schema],\n };\n }\n\n _resetRegisteredPlugins();\n for (const plugin of config.plugins ?? []) {\n config = await plugin(config);\n }\n\n return Object.freeze(config);\n}\n",
|
|
27
|
+
"/**\n * Type-safe route builder for UnifiedCommerce plugins.\n *\n * Wraps @hono/zod-openapi's createRoute() with sensible defaults:\n * - /api prefix prepended automatically\n * - Error responses (400, 401, 403, 404, 422) injected\n * - Path params auto-detected from {id} patterns\n * - POST defaults to 201, others to 200\n * - .auth() enforces login, .permission() enforces specific scope\n * - Handler receives { input, params, query, actor, services, db, logger }\n * - Return value auto-wrapped in { data: result }\n * - Errors auto-caught and mapped to { error: { code, message } }\n *\n * @example\n * ```typescript\n * import { router, z } from \"@unifiedcommerce/core\";\n *\n * const vendors = router(\"Vendors\", \"/marketplace/vendors\");\n *\n * vendors.get(\"/\").summary(\"List\").auth().handler(async ({ actor, services }) => {\n * return services.vendor.list();\n * });\n *\n * vendors.post(\"/\").summary(\"Create\").permission(\"marketplace:admin\").input(Schema)\n * .handler(async ({ input, services }) => services.vendor.create(input));\n * ```\n */\n\nimport { createRoute, z } from \"@hono/zod-openapi\";\nimport { ErrorSchema } from \"./schemas/shared\";\nimport { mapErrorToResponse, mapErrorToStatus } from \"./utils\";\nimport type { PluginRouteRegistration } from \"../../kernel/plugin/manifest\";\nimport { createScopedDb } from \"../../kernel/database/scoped-db\";\nimport { resolveOrgId } from \"../../auth/org\";\n\n// ─── Shared OpenAPI Error Responses ──────────────────────────────────────────\n\nconst errorResponses = {\n 400: { content: { \"application/json\": { schema: ErrorSchema } }, description: \"Bad request.\" },\n 401: { content: { \"application/json\": { schema: ErrorSchema } }, description: \"Unauthorized.\" },\n 403: { content: { \"application/json\": { schema: ErrorSchema } }, description: \"Forbidden.\" },\n 404: { content: { \"application/json\": { schema: ErrorSchema } }, description: \"Not found.\" },\n 422: { content: { \"application/json\": { schema: ErrorSchema } }, description: \"Validation error.\" },\n} as const;\n\nfunction wrapJson(schema: z.ZodType) {\n return { content: { \"application/json\": { schema } }, description: \"Success\" };\n}\n\nfunction extractPathParams(path: string): string[] {\n return [...path.matchAll(/\\{(\\w+)\\}/g)].map((m) => m[1]!);\n}\n\n// ─── Handler Context ─────────────────────────────────────────────────────────\n\nexport interface RouteHandlerContext {\n /** Validated request body (from .input()). Undefined if no .input() was called. */\n input: unknown;\n /** Validated query parameters (from .query()). Empty object if no .query(). */\n query: Record<string, unknown>;\n /** Path parameters, auto-extracted from {id} segments. */\n params: Record<string, string>;\n /** Authenticated actor. Guaranteed non-null if .auth() or .permission() was called. */\n actor: { userId: string; role: string; permissions: string[]; vendorId?: string | null; [key: string]: unknown } | null;\n /** Resolved organization ID. Derived from actor.organizationId, falls back to DEFAULT_ORG_ID. */\n orgId: string;\n /** Kernel services (orders, cart, inventory, etc.) */\n services: Record<string, unknown>;\n /** Drizzle database instance */\n db: unknown;\n /** Per-request structured logger */\n logger: unknown;\n /** Request ID */\n requestId: string;\n /** Raw Hono context (escape hatch) */\n raw: unknown;\n}\n\n// ─── Route Chain ─────────────────────────────────────────────────────────────\n\nclass RouteChain {\n private _summary = \"\";\n private _description = \"\";\n private _input: z.ZodType | undefined;\n private _query: z.ZodType | undefined;\n private _params: z.ZodType | undefined;\n private _requireAuth = false;\n private _requiredPermission: string | undefined;\n\n constructor(\n private method: string,\n private fullPath: string,\n private tag: string,\n private routesList: PluginRouteRegistration[],\n private pluginCtx?: { services: Record<string, unknown>; db: unknown },\n ) {\n const paramNames = extractPathParams(fullPath);\n if (paramNames.length > 0) {\n this._params = z.object(\n Object.fromEntries(paramNames.map((n) => [n, z.uuid()])),\n );\n }\n }\n\n /** Set the OpenAPI summary for this route. */\n summary(text: string) { this._summary = text; return this; }\n\n /** Set the OpenAPI description for this route. */\n description(text: string) { this._description = text; return this; }\n\n /** Set the request body schema. Only for POST/PATCH/PUT. */\n input(schema: z.ZodType) { this._input = schema; return this; }\n\n /** Set the query parameter schema. */\n query(schema: z.ZodType) { this._query = schema; return this; }\n\n /** Override the auto-detected path parameter schema. */\n params(schema: z.ZodType) { this._params = schema; return this; }\n\n /**\n * Require authentication. The handler's `actor` is guaranteed non-null.\n * Returns 401 if the request has no authenticated actor.\n */\n auth() { this._requireAuth = true; return this; }\n\n /**\n * Require a specific permission scope. Implies .auth().\n * Returns 401 if not authenticated, 403 if the actor lacks the permission.\n *\n * Permission scopes should be declared in the plugin's `permissions` manifest.\n * The wildcard `*:*` always passes.\n *\n * @example\n * ```typescript\n * vendors.post(\"/\").permission(\"marketplace:admin\").handler(...)\n * wishlist.post(\"/\").permission(\"wishlist:write\").handler(...)\n * ```\n */\n permission(scope: string) {\n this._requireAuth = true;\n this._requiredPermission = scope;\n return this;\n }\n\n /**\n * Register the handler for this route.\n *\n * The handler receives a context object with typed input, params, query,\n * actor, services, and db. Return data is auto-wrapped in { data: result }.\n * Thrown errors are auto-caught and mapped to { error: { code, message } }.\n */\n handler(fn: (ctx: RouteHandlerContext) => Promise<unknown>): void {\n const request: Record<string, unknown> = {};\n if (this._input) request.body = { ...wrapJson(this._input), required: true };\n if (this._query) request.query = this._query;\n if (this._params) request.params = this._params;\n\n const status = this.method === \"post\" ? 201 : 200;\n\n const routeConfig = createRoute({\n method: this.method as \"get\",\n path: this.fullPath,\n tags: [this.tag],\n summary: this._summary,\n ...(this._description ? { description: this._description } : {}),\n ...(Object.keys(request).length > 0 ? { request } : {}),\n responses: {\n [status]: wrapJson(z.object({ data: z.any() })),\n ...errorResponses,\n },\n });\n\n const inputSchema = this._input;\n const querySchema = this._query;\n const pathParams = extractPathParams(this.fullPath);\n const successStatus = status;\n const requireAuth = this._requireAuth;\n const requiredPermission = this._requiredPermission;\n const pluginCtx = this.pluginCtx;\n\n const honoHandler = async (c: unknown) => {\n const ctx = c as {\n req: {\n valid: (target: string) => unknown;\n param: (name: string) => string;\n };\n get: (key: string) => unknown;\n json: (data: unknown, status?: number) => unknown;\n };\n\n try {\n // ─── Auth + Permission Check ─────────────────────────────────\n // .permission() implies .auth() — both are enforced here.\n // Order: auth first (401), then permission (403).\n const actor = ctx.get(\"actor\") as RouteHandlerContext[\"actor\"];\n\n if ((requireAuth || requiredPermission) && !actor) {\n return ctx.json({ error: { code: \"UNAUTHORIZED\", message: \"Authentication required.\" } }, 401);\n }\n\n if (requiredPermission) {\n const perms = actor?.permissions ?? [];\n if (!perms.includes(requiredPermission) && !perms.includes(\"*:*\")) {\n return ctx.json({\n error: { code: \"FORBIDDEN\", message: `Permission '${requiredPermission}' is required.` },\n }, 403);\n }\n }\n\n // ─── Extract context ─────────────────────────────────────────\n const params: Record<string, string> = {};\n for (const name of pathParams) {\n params[name] = ctx.req.param(name);\n }\n\n // Use plugin context if provided (plugin routes), fallback to kernel on Hono context (core routes)\n const kernel = pluginCtx ?? (ctx.get(\"kernel\") as {\n services?: Record<string, unknown>;\n db?: unknown;\n } | undefined);\n\n // Scope the database to the actor's organization.\n // Plugin route handlers receive a db that auto-filters queries\n // and auto-stamps inserts with the actor's organizationId.\n const rawDb = kernel?.db;\n const orgId = resolveOrgId(actor);\n const scopedDb = rawDb ? createScopedDb(rawDb as Record<string, unknown>, orgId) : rawDb;\n\n const handlerCtx: RouteHandlerContext = {\n input: inputSchema ? ctx.req.valid(\"json\") : undefined,\n query: querySchema ? (ctx.req.valid(\"query\") as Record<string, unknown>) : {},\n params,\n actor,\n orgId,\n services: kernel?.services ?? {},\n db: scopedDb,\n logger: ctx.get(\"logger\"),\n requestId: (ctx.get(\"requestId\") as string) ?? \"\",\n raw: c,\n };\n\n const result = await fn(handlerCtx);\n\n if (result === undefined || result === null) {\n return ctx.json({ data: null }, successStatus);\n }\n return ctx.json({ data: result }, successStatus);\n } catch (error: unknown) {\n try {\n return ctx.json(\n mapErrorToResponse(error),\n mapErrorToStatus(error) as number,\n );\n } catch {\n // Fallback if mapErrorToResponse/mapErrorToStatus themselves throw\n return ctx.json(\n { error: { code: \"INTERNAL_ERROR\", message: \"An unexpected error occurred.\" } },\n 500,\n );\n }\n }\n };\n\n this.routesList.push({ openapi: routeConfig, handler: honoHandler as (...args: unknown[]) => unknown });\n }\n}\n\n// ─── Router ──────────────────────────────────────────────────────────────────\n\nclass RouterImpl {\n private _routes: PluginRouteRegistration[] = [];\n private _prefix: string;\n private _pluginCtx: { services: Record<string, unknown>; db: unknown } | undefined;\n\n constructor(\n private tag: string,\n prefix: string,\n pluginCtx?: { services?: Record<string, unknown>; database?: { db: unknown } },\n ) {\n // Normalize: ensure /api prefix, strip trailing slash\n let p = prefix.startsWith(\"/api\") ? prefix : `/api${prefix}`;\n p = p.replace(/\\/+$/, \"\"); // remove trailing slashes\n this._prefix = p;\n\n // If plugin context is provided, wire services + db for handler access\n if (pluginCtx) {\n this._pluginCtx = {\n services: pluginCtx.services ?? {},\n db: pluginCtx.database?.db,\n };\n }\n }\n\n /** @internal — used by RouteChain to wire plugin context into handlers */\n get pluginContext() { return this._pluginCtx; }\n\n private resolvePath(path: string): string {\n // \"/\" means \"the resource root\" → just the prefix, no trailing slash\n if (path === \"/\") return this._prefix;\n return (this._prefix + path).replace(/\\/\\/+/g, \"/\");\n }\n\n get(path: string) { return new RouteChain(\"get\", this.resolvePath(path), this.tag, this._routes, this._pluginCtx); }\n post(path: string) { return new RouteChain(\"post\", this.resolvePath(path), this.tag, this._routes, this._pluginCtx); }\n patch(path: string) { return new RouteChain(\"patch\", this.resolvePath(path), this.tag, this._routes, this._pluginCtx); }\n delete(path: string) { return new RouteChain(\"delete\", this.resolvePath(path), this.tag, this._routes, this._pluginCtx); }\n put(path: string) { return new RouteChain(\"put\", this.resolvePath(path), this.tag, this._routes, this._pluginCtx); }\n\n /** Returns all registered routes as PluginRouteRegistration[] */\n routes(): PluginRouteRegistration[] { return this._routes; }\n}\n\n/**\n * Create a typed route group for plugin routes.\n *\n * @param tag — OpenAPI tag for Swagger UI grouping\n * @param prefix — Path prefix without /api (e.g., \"/marketplace/vendors\"). /api is prepended automatically.\n * @param ctx — Optional PluginContext. When provided, handler receives { services, db } from the plugin.\n *\n * @example\n * ```typescript\n * // In plugin routes callback:\n * routes: (ctx) => {\n * const r = router(\"Vendors\", \"/marketplace/vendors\", ctx);\n * r.get(\"/\").summary(\"List\").handler(async ({ services }) => {\n * return (services as VendorServices).vendor.list();\n * });\n * return r.routes();\n * }\n * ```\n */\nexport function router(tag: string, prefix: string, ctx?: { services?: Record<string, unknown>; database?: { db: unknown } }): RouterImpl {\n return new RouterImpl(tag, prefix, ctx);\n}\n",
|
|
28
|
+
"import { z } from \"@hono/zod-openapi\";\n\n// ─── Error Response ──────────────────────────────────────────────────────────\n\nexport const ErrorSchema = z.object({\n error: z.object({\n code: z.string().openapi({ example: \"VALIDATION_FAILED\" }),\n message: z.string().openapi({ example: \"cartId: Invalid uuid\" }),\n }),\n}).openapi(\"Error\");\n\n// ─── Pagination ──────────────────────────────────────────────────────────────\n\nexport const PaginationQuerySchema = z.object({\n page: z.string().optional().openapi({ example: \"1\" }),\n limit: z.string().optional().openapi({ example: \"20\" }),\n});\n\nexport const PaginationMetaSchema = z.object({\n page: z.number(),\n limit: z.number(),\n total: z.number().optional(),\n}).openapi(\"PaginationMeta\");\n\n// ─── Common Params ───────────────────────────────────────────────────────────\n\nexport const UuidParamSchema = z.object({\n id: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n});\n\nexport const IdOrSlugParamSchema = z.object({\n idOrSlug: z.string().min(1).openapi({ example: \"my-product\" }),\n});\n\n// ─── Common Responses ────────────────────────────────────────────────────────\n\nexport const DeletedResponseSchema = z.object({\n data: z.object({ deleted: z.literal(true) }),\n}).openapi(\"DeletedResponse\");\n\nexport const errorResponses = {\n 400: {\n content: { \"application/json\": { schema: ErrorSchema } },\n description: \"Business logic error.\",\n },\n 401: {\n content: { \"application/json\": { schema: ErrorSchema } },\n description: \"Authentication required.\",\n },\n 403: {\n content: { \"application/json\": { schema: ErrorSchema } },\n description: \"Insufficient permissions.\",\n },\n 404: {\n content: { \"application/json\": { schema: ErrorSchema } },\n description: \"Resource not found.\",\n },\n 422: {\n content: { \"application/json\": { schema: ErrorSchema } },\n description: \"Validation error.\",\n },\n} as const;\n",
|
|
29
|
+
"export interface CommerceError {\n code: string;\n message: string;\n details?: unknown;\n}\n\nexport interface FieldError {\n field: string;\n message: string;\n}\n\nexport class CommerceNotFoundError extends Error implements CommerceError {\n code = \"NOT_FOUND\" as const;\n constructor(\n message: string,\n public details?: unknown,\n ) {\n super(message);\n this.name = \"CommerceNotFoundError\";\n }\n}\n\nexport class CommerceValidationError extends Error implements CommerceError {\n code = \"VALIDATION_FAILED\" as const;\n constructor(\n message: string,\n public fieldErrors?: FieldError[],\n public details?: unknown,\n ) {\n super(message);\n this.name = \"CommerceValidationError\";\n }\n}\n\nexport class CommerceForbiddenError extends Error implements CommerceError {\n code = \"FORBIDDEN\" as const;\n constructor(\n message: string,\n public details?: unknown,\n ) {\n super(message);\n this.name = \"CommerceForbiddenError\";\n }\n}\n\nexport class CommerceConflictError extends Error implements CommerceError {\n code = \"CONFLICT\" as const;\n constructor(\n message: string,\n public details?: unknown,\n ) {\n super(message);\n this.name = \"CommerceConflictError\";\n }\n}\n\nexport class CommerceInvalidTransitionError extends Error implements CommerceError {\n code = \"INVALID_TRANSITION\" as const;\n constructor(\n message: string,\n public details?: unknown,\n ) {\n super(message);\n this.name = \"CommerceInvalidTransitionError\";\n }\n}\n\nexport function isCommerceError(value: unknown): value is CommerceError {\n if (!value || typeof value !== \"object\") return false;\n return \"code\" in value && \"message\" in value;\n}\n\nexport function toCommerceError(error: unknown): CommerceError {\n if (isCommerceError(error)) {\n return error;\n }\n if (error instanceof Error) {\n return {\n code: \"INTERNAL_ERROR\",\n message: error.message,\n details: { name: error.name },\n };\n }\n return {\n code: \"INTERNAL_ERROR\",\n message: \"Unexpected server error\",\n details: error,\n };\n}\n",
|
|
30
|
+
"import { toCommerceError } from \"./errors\";\nimport type { ContentfulStatusCode } from \"hono/utils/http-status\";\n\nconst statusByCode: Record<string, ContentfulStatusCode> = {\n NOT_FOUND: 404,\n VALIDATION_FAILED: 422,\n FORBIDDEN: 403,\n CONFLICT: 409,\n INVALID_TRANSITION: 422,\n};\n\nexport function mapErrorToStatus(error: unknown): ContentfulStatusCode {\n const normalized = toCommerceError(error);\n return statusByCode[normalized.code] ?? 500;\n}\n",
|
|
31
|
+
"import type { CommerceError } from \"../../kernel/errors\";\nimport { mapErrorToStatus } from \"../../kernel/error-mapper\";\nimport { toCommerceError } from \"../../kernel/errors\";\nimport type { Actor } from \"../../auth/types\";\n\n/**\n * Shared Hono environment type for all sub-routers.\n * Matches the Variables set by middleware in the top-level server app.\n */\nexport type AppEnv = {\n Variables: {\n actor: Actor | null;\n requestId: string;\n logger: unknown;\n kernel: unknown;\n };\n};\n\nconst MAX_PAGE_LIMIT = 100;\n\nexport function parsePagination(query: Record<string, string | undefined>): {\n page: number;\n limit: number;\n} {\n const page = Number.parseInt(query.page ?? \"1\", 10);\n const limit = Number.parseInt(query.limit ?? \"20\", 10);\n return {\n page: Number.isFinite(page) && page > 0 ? page : 1,\n limit: Math.min(MAX_PAGE_LIMIT, Number.isFinite(limit) && limit > 0 ? limit : 20),\n };\n}\n\nexport function parseInclude(value?: string): Set<string> {\n if (!value) return new Set();\n return new Set(\n value\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean),\n );\n}\n\n/**\n * Map an error to a safe client response. Internal errors are sanitized\n * to prevent leaking SQL, schema, or stack trace details.\n */\nexport function mapErrorToResponse(error: unknown): { error: { code: string; message: string } } {\n const ce = toCommerceError(error);\n if (ce.code === \"INTERNAL_ERROR\") {\n // Sanitize internal errors -- do not expose raw messages to clients\n return { error: { code: \"INTERNAL_ERROR\", message: \"An unexpected error occurred.\" } };\n }\n return { error: { code: ce.code, message: ce.message } };\n}\n\nexport { mapErrorToStatus };\n\n/**\n * Hono middleware that requires a specific permission on the actor.\n * Returns 401 if no actor, 403 if permission denied.\n * Usage: router.post(\"/\", requirePerm(\"webhooks:manage\"), handler);\n */\nexport function requirePerm(permission: string) {\n return async (c: { get(key: string): unknown; json(data: unknown, status: number): unknown }, next: () => Promise<void>) => {\n const actor = c.get(\"actor\") as { permissions?: string[] } | null;\n if (!actor) {\n return c.json({ error: { code: \"UNAUTHORIZED\", message: \"Authentication required.\" } }, 401);\n }\n const perms = actor.permissions ?? [];\n if (perms.includes(permission) || perms.includes(\"*:*\")) {\n await next();\n return;\n }\n // Check resource-level wildcard (e.g., \"catalog:*\" matches \"catalog:create\")\n const [resource] = permission.split(\":\");\n if (resource && perms.includes(`${resource}:*`)) {\n await next();\n return;\n }\n return c.json({ error: { code: \"FORBIDDEN\", message: `Permission '${permission}' is required.` } }, 403);\n };\n}\n\nexport function parseSort(\n value?: string,\n):\n | {\n field: \"createdAt\" | \"updatedAt\" | \"slug\";\n direction: \"asc\" | \"desc\";\n}\n | undefined {\n if (!value) return undefined;\n const [fieldRaw, directionRaw] = value.split(\":\");\n const selectedField = fieldRaw ?? \"createdAt\";\n const field = [\"createdAt\", \"updatedAt\", \"slug\"].includes(selectedField)\n ? (selectedField as \"createdAt\" | \"updatedAt\" | \"slug\")\n : \"createdAt\";\n const direction = directionRaw === \"asc\" ? \"asc\" : \"desc\";\n return { field, direction };\n}\n\nexport function isUUID(value: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);\n}\n",
|
|
32
|
+
"/**\n * Scoped DB Proxy\n *\n * Wraps a Drizzle PgDatabase instance so that INSERT operations on\n * org-scoped tables automatically include the actor's organizationId.\n *\n * Plugin route handlers receive this scoped db via the router() builder.\n * They write normal Drizzle inserts without ever mentioning organizationId:\n *\n * const [card] = await db.insert(giftCards)\n * .values({ code: \"ABC\", balance: 5000 })\n * .returning();\n * // organizationId is auto-set from the actor context\n *\n * SELECT/UPDATE/DELETE scoping is handled at the repository/service layer\n * via resolveOrgId(). The proxy focuses on INSERT auto-stamping because\n * that is the operation most commonly forgotten by plugin developers.\n */\n\nimport { getTableColumns } from \"drizzle-orm\";\nimport type { PgTable } from \"drizzle-orm/pg-core\";\n\nfunction isOrgScoped(table: PgTable): boolean {\n const columns = getTableColumns(table);\n return \"organizationId\" in columns;\n}\n\nexport function createScopedDb<TDb>(rawDb: TDb, organizationId: string): TDb {\n if (!rawDb || typeof rawDb !== \"object\") return rawDb;\n\n return new Proxy(rawDb as Record<string, unknown>, {\n get(target, prop, receiver) {\n const value = Reflect.get(target, prop, receiver);\n\n if (prop === \"insert\" && typeof value === \"function\") {\n return (table: PgTable) => {\n const builder = value.call(target, table);\n if (!isOrgScoped(table)) return builder;\n\n // Wrap .values() to auto-inject organizationId\n const originalValues = (builder as Record<string, unknown>).values;\n if (typeof originalValues !== \"function\") return builder;\n\n return new Proxy(builder as Record<string, unknown>, {\n get(t, p, r) {\n if (p === \"values\") {\n return (data: unknown) => {\n const stamp = (row: Record<string, unknown>) => ({\n ...row,\n organizationId,\n });\n const stamped = Array.isArray(data)\n ? data.map(stamp)\n : stamp(data as Record<string, unknown>);\n return originalValues.call(t, stamped);\n };\n }\n const v = Reflect.get(t, p, r);\n return typeof v === \"function\" ? v.bind(t) : v;\n },\n });\n };\n }\n\n return typeof value === \"function\" ? value.bind(target) : value;\n },\n }) as TDb;\n}\n",
|
|
33
|
+
"/**\n * webhookRouter() — route builder for external webhook receivers.\n *\n * Unlike router() which uses UC authentication (.auth(), .permission()),\n * webhookRouter() uses HMAC signature verification. This is for routes\n * that receive callbacks from external services (Shopify, WooCommerce,\n * Stripe, BNPL providers) that authenticate via provider-specific signatures.\n *\n * Provides typed access to kernel.services, kernel.database.db, and\n * kernel.logger without casting through `unknown`.\n *\n * Usage:\n *\n * import { webhookRouter } from \"@unifiedcommerce/core\";\n *\n * export function createMyWebhookRoutes(kernel: Kernel) {\n * const { app, services, db, logger } = webhookRouter(kernel);\n *\n * app.post(\"/product-updated\", async (c) => {\n * const body = await c.req.json();\n * await services.catalog.update(body.id, { ... }, systemActor);\n * return c.json({ status: \"ok\" });\n * });\n *\n * return app;\n * }\n */\n\nimport { Hono } from \"hono\";\nimport type { Kernel } from \"../../runtime/kernel\";\n\nexport interface WebhookRouterResult {\n /** Raw Hono app — mount routes on this. No UC auth middleware attached. */\n app: Hono;\n /** Kernel services (catalog, inventory, orders, etc.). Typed properly. */\n services: Kernel[\"services\"];\n /** Drizzle database instance for direct queries. */\n db: Kernel[\"database\"][\"db\"];\n /** Structured Pino logger. */\n logger: Kernel[\"logger\"];\n}\n\nexport function webhookRouter(kernel: Kernel): WebhookRouterResult {\n return {\n app: new Hono(),\n services: kernel.services,\n db: kernel.database.db,\n logger: kernel.logger,\n };\n}\n",
|
|
34
|
+
"/**\n * Shared SSRF prevention utilities.\n *\n * Used by both webhook delivery (DNS rebinding check) and connector URL\n * validation (store URL check) to reject private/internal IP addresses.\n */\n\n/**\n * Returns true if the given IP address falls within a private, loopback,\n * link-local, or otherwise non-routable range.\n */\nexport function isPrivateIp(ip: string): boolean {\n // IPv6 loopback / link-local / mapped\n if (ip === \"::1\" || ip === \"::\") return true;\n if (ip.startsWith(\"fe80:\")) return true;\n\n // IPv6-mapped IPv4 (e.g. ::ffff:127.0.0.1) — extract the IPv4 portion\n const mappedMatch = ip.match(/^::ffff:(\\d+\\.\\d+\\.\\d+\\.\\d+)$/i);\n if (mappedMatch) {\n return isPrivateIpv4(mappedMatch[1]!);\n }\n\n return isPrivateIpv4(ip);\n}\n\nfunction isPrivateIpv4(ip: string): boolean {\n const parts = ip.split(\".\").map(Number);\n if (parts.length !== 4 || parts.some((n) => isNaN(n))) return false;\n\n const [a, b] = parts;\n if (a === undefined || b === undefined) return false;\n\n if (a === 127) return true; // loopback 127.0.0.0/8\n if (a === 10) return true; // RFC 1918 class A\n if (a === 172 && b >= 16 && b <= 31) return true; // RFC 1918 class B\n if (a === 192 && b === 168) return true; // RFC 1918 class C\n if (a === 169 && b === 254) return true; // link-local / AWS IMDS\n if (a === 0) return true; // unspecified\n\n return false;\n}\n\n/**\n * Checks whether a URL string points to a private/internal IP address or\n * hostname. This performs a string-level check only (no DNS resolution).\n *\n * For DNS rebinding protection, use `isPrivateIp` after resolving the hostname.\n */\nexport function isPrivateUrl(urlStr: string): boolean {\n try {\n const parsed = new URL(urlStr);\n const hostname = parsed.hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n\n // Direct hostname matches\n if (hostname === \"localhost\" || hostname.endsWith(\".localhost\")) return true;\n if (hostname === \"::1\" || hostname === \"::\") return true;\n if (hostname.startsWith(\"::ffff:\")) return true;\n if (hostname.startsWith(\"fe80:\")) return true;\n if (hostname.endsWith(\".local\")) return true;\n if (hostname.endsWith(\".internal\")) return true;\n\n // Cloud metadata endpoints\n if (hostname === \"169.254.169.254\") return true;\n if (hostname === \"metadata.google.internal\") return true;\n\n // Check if hostname is a raw IP in private ranges\n return isPrivateIpv4(hostname);\n } catch {\n return true; // Invalid URLs are blocked\n }\n}\n",
|
|
35
|
+
"import { Hono } from \"hono\";\nimport { OpenAPIHono } from \"@hono/zod-openapi\";\nimport { cors } from \"hono/cors\";\nimport { csrf } from \"hono/csrf\";\nimport { bodyLimit } from \"hono/body-limit\";\nimport { rateLimiter } from \"hono-rate-limiter\";\nimport type { Actor } from \"../auth/types\";\nimport type { AuthInstance } from \"../auth/setup\";\nimport type { CommerceConfig } from \"../config/types\";\nimport { createAuth } from \"../auth/setup\";\nimport { authMiddleware } from \"../auth/middleware\";\nimport { createMCPHandler } from \"../interfaces/mcp/transport\";\nimport { createRestRoutes } from \"../interfaces/rest\";\nimport { createCustomerPortalRoutes } from \"../interfaces/rest/customer-portal\";\nimport { createKernel } from \"./kernel\";\nimport { ensureDefaultOrg } from \"../auth/org\";\nimport { createLogger, type Logger } from \"./logger\";\nimport { createCommerce, type CommerceInstance } from \"./commerce\";\n\ntype ServerEnv = {\n Variables: {\n auth: AuthInstance;\n actor: Actor | null;\n requestId: string;\n logger: Logger;\n };\n};\n\n/**\n * Create a full HTTP server (Hono) with all REST routes, auth, and middleware.\n *\n * For server-side frameworks (Next.js, TanStack Start, SvelteKit), use\n * `createCommerce()` instead — it gives you a local API without HTTP overhead.\n */\nexport async function createServer(config: CommerceConfig) {\n const commerce = await createCommerce(config);\n const { kernel, auth, logger } = commerce;\n const isProdEnv = process.env.NODE_ENV === \"production\";\n const app = new OpenAPIHono<ServerEnv>({\n defaultHook: (result, c) => {\n if (!result.success) {\n return c.json({\n error: {\n code: \"VALIDATION_FAILED\",\n message: isProdEnv\n ? \"Invalid input.\"\n : result.error.issues\n .map((i) => `${i.path.join(\".\")}: ${i.message}`)\n .join(\"; \"),\n },\n }, 422);\n }\n },\n });\n\n // ─── Security Guards ──────────────────────────────────────────────\n if (config.auth?.enableDevKey && process.env.NODE_ENV === \"production\") {\n throw new Error(\n \"FATAL: Dev key MUST NOT be enabled in production. \" +\n \"Set auth.enableDevKey: false in production config.\",\n );\n }\n if (config.auth?.enableDevKey && process.env.NODE_ENV !== \"development\") {\n logger.warn(\n \"Dev key is enabled outside NODE_ENV=development. \" +\n \"Set auth.enableDevKey: false in production config to disable the dev backdoor.\",\n );\n }\n\n // ─── Process Crash Handlers (F4) ─────────────────────────────────────\n process.on(\"unhandledRejection\", (reason) => {\n logger.fatal({ err: reason }, \"unhandled promise rejection -- exiting\");\n process.exit(1);\n });\n\n process.on(\"uncaughtException\", (err) => {\n logger.fatal({ err }, \"uncaught exception -- exiting\");\n process.exit(1);\n });\n\n // ─── Security Response Headers ──────────────────────────────────────\n app.use(\"*\", async (c, next) => {\n c.header(\"X-Content-Type-Options\", \"nosniff\");\n c.header(\"X-Frame-Options\", \"DENY\");\n c.header(\"Referrer-Policy\", \"strict-origin-when-cross-origin\");\n c.header(\"Permissions-Policy\", \"camera=(), microphone=(), geolocation=()\");\n if (isProdEnv) {\n c.header(\"Strict-Transport-Security\", \"max-age=31536000; includeSubDomains\");\n }\n await next();\n });\n\n // ─── Request ID + Logging (F2, F12) ──────────────────────────────────\n app.use(\"*\", async (c, next) => {\n const requestId = c.req.header(\"x-request-id\") ?? crypto.randomUUID();\n c.header(\"x-request-id\", requestId);\n c.set(\"requestId\", requestId);\n const child = logger.child({ requestId, method: c.req.method, path: c.req.path });\n c.set(\"logger\", child);\n\n const start = performance.now();\n await next();\n\n // Sanitize ZodError responses in production.\n // @hono/zod-openapi returns { success: false, error: { name: \"ZodError\" } }\n // which leaks schema details. The library does not respect defaultHook for\n // this format, so we intercept at the response level.\n if (isProdEnv && c.res.status >= 400 && c.res.status < 500) {\n const ct = c.res.headers.get(\"content-type\");\n if (ct?.includes(\"json\")) {\n try {\n const body = await c.res.clone().json();\n if (body?.error?.name === \"ZodError\") {\n c.res = new Response(\n JSON.stringify({ error: { code: \"VALIDATION_FAILED\", message: \"Invalid input.\" } }),\n { status: 422, headers: { \"content-type\": \"application/json\" } },\n );\n }\n } catch { /* non-parseable, skip */ }\n }\n }\n\n const duration = Math.round(performance.now() - start);\n\n child.info({ status: c.res.status, durationMs: duration }, \"request completed\");\n });\n\n // ─── CORS (hardened by default) ──────────────────────────────────────\n const trustedOrigins = config.auth?.trustedOrigins ?? [];\n app.use(\"*\", cors({\n origin: trustedOrigins.length > 0\n ? trustedOrigins\n : (process.env.NODE_ENV === \"production\" ? [] : [\"http://localhost:*\"]),\n credentials: true,\n allowMethods: [\"GET\", \"POST\", \"PATCH\", \"PUT\", \"DELETE\", \"OPTIONS\"],\n allowHeaders: [\"Content-Type\", \"Authorization\", \"x-api-key\", \"x-request-id\"],\n maxAge: 86400,\n }));\n\n // ─── CSRF Protection (F14) ──────────────────────────────────────────\n app.use(\"/api/*\", csrf({\n origin: trustedOrigins.length > 0\n ? trustedOrigins\n : (process.env.NODE_ENV === \"production\" ? [] : [\"http://localhost:*\"]),\n }));\n\n // ─── Body Size Limit (F6) ──────────────────────────────────────────\n app.use(\"*\", bodyLimit({\n maxSize: 1024 * 1024, // 1 MB default\n onError: (c) => c.json({\n error: { code: \"PAYLOAD_TOO_LARGE\", message: \"Request body exceeds 1MB limit.\" },\n }, 413),\n }));\n\n // ─── Rate Limiting (F1) ──────────────────────────────────────────────\n // Trust X-Forwarded-For ONLY from a known reverse proxy IP.\n // Set TRUSTED_PROXY_IP env var to the proxy's IP (e.g., \"127.0.0.1\").\n const trustedProxyIp = process.env.TRUSTED_PROXY_IP;\n const getClientIp = (c: { req: { raw: unknown; header: (name: string) => string | undefined } }): string => {\n const raw = c.req.raw as { socket?: { remoteAddress?: string } };\n const remoteAddress = raw.socket?.remoteAddress;\n // Only trust X-Forwarded-For when the direct connection is from a trusted proxy\n if (trustedProxyIp && remoteAddress === trustedProxyIp) {\n const xff = c.req.header(\"x-forwarded-for\")?.split(\",\")[0]?.trim();\n if (xff) return xff;\n }\n return remoteAddress ?? \"unknown\";\n };\n const keyGenerator = getClientIp;\n\n app.use(\"/api/auth/*\", rateLimiter({\n windowMs: 60 * 1000,\n limit: config.rateLimits?.auth ?? 10,\n keyGenerator,\n }));\n\n app.use(\"/api/checkout\", rateLimiter({\n windowMs: 60 * 1000,\n limit: config.rateLimits?.checkout ?? 5,\n keyGenerator,\n }));\n\n app.use(\"/api/*\", rateLimiter({\n windowMs: 60 * 1000,\n limit: config.rateLimits?.api ?? 100,\n keyGenerator,\n }));\n\n // ─── Custom Middleware ──────────────────────────────────────────────\n if (config.middleware) {\n for (const middleware of config.middleware) {\n app.use(\"*\", middleware);\n }\n }\n\n // ─── Auth ──────────────────────────────────────────────────────────\n app.use(\"/api/auth/*\", async (c, next) => {\n if (c.req.path.startsWith(\"/api/auth/pos/\")) {\n await next();\n return;\n }\n return auth.handler(c.req.raw);\n });\n\n app.use(\"*\", authMiddleware(auth, config));\n app.use(\"*\", async (c, next) => {\n c.set(\"auth\", auth);\n await next();\n });\n\n // ─── Global Error Handler ─────────────────────────────────────────\n // Sanitize errors in production — no stack traces, no class names, no schema details\n const isProd = process.env.NODE_ENV === \"production\";\n app.onError((err, c) => {\n // Catch ZodError from @hono/zod-openapi validation (bypasses defaultHook)\n if (err.constructor?.name === \"ZodError\" || \"issues\" in err) {\n if (isProd) {\n return c.json(\n { error: { code: \"VALIDATION_FAILED\", message: \"Invalid input.\" } },\n 422,\n );\n }\n const issues = (err as { issues?: Array<{ path: string[]; message: string }> }).issues ?? [];\n return c.json(\n {\n error: {\n code: \"VALIDATION_FAILED\",\n message: issues.map((i) => `${i.path.join(\".\")}: ${i.message}`).join(\"; \"),\n },\n },\n 422,\n );\n }\n\n if (isProd) {\n logger.error({ err }, \"unhandled request error\");\n return c.json(\n { error: { code: \"INTERNAL_ERROR\", message: \"An unexpected error occurred.\" } },\n 500,\n );\n }\n return c.json(\n { error: { code: \"INTERNAL_ERROR\", message: err.message } },\n 500,\n );\n });\n\n // ─── Routes ──────────────────────────────────────────────────────────\n app.route(\"/api\", createRestRoutes(kernel));\n app.route(\"/mcp\", createMCPHandler(kernel, config.mcpTools));\n app.route(\"/api/me\", createCustomerPortalRoutes(kernel));\n\n if (config.routes) {\n config.routes(app as unknown as Hono, kernel);\n }\n\n // OpenAPI spec — disabled in production unless explicitly enabled\n const exposeSpec = config.exposeOpenApiSpec ?? !isProd;\n if (exposeSpec) {\n app.doc(\"/api/doc\", {\n openapi: \"3.0.0\",\n info: {\n title: \"UnifiedCommerce API\",\n version: config.version ?? \"0.0.1\",\n description: \"Headless commerce engine REST API. Includes core and plugin endpoints.\",\n },\n });\n } else {\n app.get(\"/api/doc\", (c) => c.json({ error: { code: \"NOT_FOUND\", message: \"Not found.\" } }, 404));\n }\n\n // ─── Job Queue ───────────────────────────────────────────────────────\n // Background job processing: webhook delivery, scheduled orders, email tasks.\n //\n // Three runner strategies (inspired by Payload CMS):\n // 1. autorun: in-process polling (long-running servers)\n // 2. GET /api/jobs/run: cron endpoint (serverless — Vercel, Cloudflare)\n // 3. runPendingJobs() export (custom worker process)\n\n const { runPendingJobs } = await import(\"../kernel/jobs/runner\");\n const taskMap = new Map<string, unknown>();\n for (const task of config.jobs?.tasks ?? []) {\n taskMap.set((task as unknown as { slug?: string; name?: string }).slug ?? (task as unknown as { name: string }).name, task);\n }\n\n const runJobs = async (queue?: string, limit?: number) => {\n return runPendingJobs({\n db: kernel.database.db as Parameters<typeof runPendingJobs>[0][\"db\"],\n tasks: taskMap as Parameters<typeof runPendingJobs>[0][\"tasks\"],\n queue: queue ?? \"default\",\n limit: limit ?? 10,\n logger: logger as Parameters<typeof runPendingJobs>[0][\"logger\"],\n services: kernel.services as unknown as Parameters<typeof runPendingJobs>[0][\"services\"],\n });\n };\n\n // Strategy 1: Built-in cron endpoint for serverless deployments.\n // Point Vercel Cron or Cloudflare Cron Trigger at GET /api/jobs/run\n // Optional query params: ?queue=emails&limit=20\n app.get(\"/api/jobs/run\", async (c) => {\n // Always require admin — cron triggers must authenticate\n const actor = c.get(\"actor\") as { permissions?: string[] } | null;\n if (!actor?.permissions?.includes(\"*:*\")) {\n return c.json({ error: { code: \"FORBIDDEN\", message: \"Job runner requires admin access\" } }, 403);\n }\n\n const queue = c.req.query(\"queue\") ?? \"default\";\n const limit = parseInt(c.req.query(\"limit\") ?? \"10\", 10);\n\n try {\n const result = await runJobs(queue, limit);\n return c.json({ data: result });\n } catch (err) {\n logger.error({ err }, \"Job runner endpoint failed\");\n return c.json({ error: { code: \"INTERNAL_ERROR\", message: \"Job processing failed\" } }, 500);\n }\n });\n\n // Strategy 2: In-process polling for long-running servers (ECS, Cloud Run, Docker).\n // Enable via config.jobs.autorun.enabled = true\n if (config.jobs?.autorun?.enabled) {\n const intervalMs = config.jobs.autorun.intervalMs ?? 10_000;\n\n const jobInterval = setInterval(async () => {\n try {\n await runJobs();\n } catch (err) {\n logger.error({ err }, \"Job runner iteration failed\");\n }\n }, intervalMs);\n\n const cleanup = () => clearInterval(jobInterval);\n process.on(\"SIGTERM\", cleanup);\n process.on(\"SIGINT\", cleanup);\n\n logger.info({ intervalMs }, \"Job queue autorun started (in-process polling)\");\n } else {\n logger.info(\n \"Job queue autorun disabled. Use GET /api/jobs/run for serverless cron, \" +\n \"or set config.jobs.autorun.enabled = true for in-process polling.\",\n );\n }\n\n return { app, kernel, logger, commerce };\n}\n",
|
|
36
|
+
"import { timingSafeEqual } from \"node:crypto\";\nimport type { MiddlewareHandler } from \"hono\";\nimport type { AuthSessionLike, CommerceConfig } from \"../config/types\";\nimport type { Actor } from \"./types\";\nimport type { AuthInstance } from \"./setup\";\nimport { DEFAULT_ORG_ID } from \"./org\";\n\nfunction resolvePermissions(\n session: AuthSessionLike,\n config: CommerceConfig,\n): string[] {\n const role = session.session.activeOrganizationRole;\n if (!role) {\n return (\n config.auth?.customerPermissions ?? [\n \"catalog:read\",\n \"cart:create\",\n \"cart:read\",\n \"cart:update\",\n \"orders:create\",\n \"orders:read:own\",\n \"customers:read:self\",\n \"customers:update:self\",\n ]\n );\n }\n const roleConfig = config.auth?.roles?.[role];\n return roleConfig ? roleConfig.permissions : [];\n}\n\nexport function authMiddleware(\n auth: AuthInstance,\n config: CommerceConfig,\n): MiddlewareHandler {\n return async (c, next) => {\n const session = (await auth.api.getSession({\n headers: c.req.raw.headers,\n })) as AuthSessionLike | null;\n\n if (session) {\n c.set(\"actor\", {\n type: \"user\",\n userId: session.user.id,\n email: session.user.email ?? null,\n name: session.user.name ?? \"User\",\n vendorId: session.user.vendorId ?? null,\n organizationId: session.session.activeOrganizationId ?? null,\n role: session.session.activeOrganizationRole ?? \"customer\",\n permissions: resolvePermissions(session, config),\n } satisfies Actor);\n await next();\n return;\n }\n\n // Extract API key from headers\n const apiKeyHeader =\n c.req.header(\"x-api-key\") ??\n c.req.header(\"authorization\")?.replace(\"Bearer \", \"\");\n\n if (\n apiKeyHeader &&\n config.auth?.apiKeys?.enabled &&\n auth.api.verifyApiKey\n ) {\n try {\n const keyResult = await auth.api.verifyApiKey({ key: apiKeyHeader });\n if (keyResult) {\n c.set(\"actor\", {\n type: \"api_key\",\n userId: keyResult.userId,\n email: null,\n name: keyResult.name ?? \"API Key\",\n vendorId: null,\n organizationId: (keyResult as Record<string, unknown>).organizationId as string ?? DEFAULT_ORG_ID,\n role: \"api_key\",\n permissions:\n keyResult.permissions ??\n config.auth?.apiKeys?.defaultPermissions ??\n [],\n } satisfies Actor);\n await next();\n return;\n }\n } catch {\n // ignore invalid key\n }\n }\n\n // Config-driven dev key (OFF by default, must be explicitly enabled)\n if (\n !c.get(\"actor\") &&\n apiKeyHeader &&\n config.auth?.enableDevKey &&\n config.auth.devKey &&\n apiKeyHeader.length === config.auth.devKey.length &&\n timingSafeEqual(Buffer.from(apiKeyHeader), Buffer.from(config.auth.devKey))\n ) {\n c.set(\"actor\", {\n type: \"api_key\",\n userId: \"dev-staff\",\n email: \"dev@local\",\n name: \"Dev Admin (dev key)\",\n vendorId: null,\n organizationId: DEFAULT_ORG_ID,\n role: \"owner\",\n permissions: [\"*:*\"],\n } satisfies Actor);\n }\n\n if (!c.get(\"actor\")) {\n c.set(\"actor\", null);\n }\n await next();\n };\n}\n",
|
|
37
|
+
"import { Hono } from \"hono\";\nimport { streamSSE, type SSEStreamingApi } from \"hono/streaming\";\nimport type { MCPTool } from \"../../config/types\";\nimport type { Kernel } from \"../../runtime/kernel\";\nimport { registerMCPCapabilities } from \"./server\";\n\nasync function handleMCPSession(\n stream: SSEStreamingApi,\n capabilities: ReturnType<typeof registerMCPCapabilities>,\n): Promise<void> {\n await stream.writeSSE({\n event: \"ready\",\n data: JSON.stringify({\n tools: capabilities.tools.map((tool) => ({ name: tool.name, description: tool.description })),\n resources: capabilities.resources.map((resource) => ({ uri: resource.uri, name: resource.name })),\n }),\n });\n}\n\nexport function createMCPHandler(kernel: Kernel, customTools?: (kernel: Kernel) => MCPTool[]) {\n const router = new Hono();\n const capabilities = registerMCPCapabilities(kernel);\n\n if (customTools) {\n capabilities.tools.push(...customTools(kernel));\n }\n\n if (kernel.mcpTools.length > 0) {\n capabilities.tools.push(...kernel.mcpTools);\n }\n\n if (kernel.mcpResources.length > 0) {\n capabilities.resources.push(...kernel.mcpResources);\n }\n\n router.get(\"/sse\", async (c) =>\n streamSSE(c, async (stream) => {\n await handleMCPSession(stream, capabilities);\n }),\n );\n\n router.post(\"/tools/:toolName\", async (c) => {\n const tool = capabilities.tools.find((item) => item.name === c.req.param(\"toolName\"));\n if (!tool) return c.json({ error: \"Tool not found\" }, 404);\n\n return c.json(await tool.handler(await c.req.json<unknown>()));\n });\n\n router.get(\"/resources\", async (c) => {\n return c.json({\n data: capabilities.resources.map((resource) => ({\n uri: resource.uri,\n name: resource.name,\n description: resource.description,\n mimeType: resource.mimeType,\n })),\n });\n });\n\n router.get(\"/resources/:resourceId\", async (c) => {\n const uri = decodeURIComponent(c.req.param(\"resourceId\"));\n const resource = capabilities.resources.find((item) => item.uri === uri);\n if (!resource) return c.json({ error: \"Resource not found\" }, 404);\n return c.json(await resource.handler());\n });\n\n return router;\n}\n",
|
|
38
|
+
"import type { Result } from \"../../kernel/result\";\n\n// ─── Query Params (unchanged from existing API) ─────────────────────────────\n\nexport interface AnalyticsTimeDimension {\n dimension: string;\n granularity?: \"day\" | \"week\" | \"month\" | \"year\";\n dateRange?: [string, string] | string;\n}\n\nexport interface AnalyticsFilter {\n member: string;\n operator:\n | \"equals\"\n | \"notEquals\"\n | \"contains\"\n | \"in\"\n | \"notIn\"\n | \"gt\"\n | \"gte\"\n | \"lt\"\n | \"lte\"\n | \"beforeDate\"\n | \"afterDate\"\n | \"inDateRange\";\n values?: string[];\n}\n\nexport interface AnalyticsQueryParams {\n measures: string[];\n dimensions?: string[];\n timeDimensions?: AnalyticsTimeDimension[];\n filters?: AnalyticsFilter[];\n order?: Record<string, \"asc\" | \"desc\">;\n limit?: number;\n}\n\n// ─── Query Result ────────────────────────────────────────────────────────────\n\nexport interface AnalyticsQueryResult {\n query: AnalyticsQueryParams;\n rows: Record<string, unknown>[];\n source: string;\n}\n\n// ─── Model / Meta ────────────────────────────────────────────────────────────\n\nexport interface AnalyticsModelDefinition {\n name: string;\n measures: string[];\n dimensions: string[];\n segments?: string[];\n source: \"builtin\" | \"plugin\" | \"custom-schema\";\n raw?: unknown;\n}\n\nexport interface AnalyticsMeta {\n models: AnalyticsModelDefinition[];\n measures: string[];\n dimensions: string[];\n segments: string[];\n}\n\n// ─── Analytics Model (declarative SQL mapping) ──────────────────────────────\n\nexport type MeasureType = \"count\" | \"sum\" | \"avg\" | \"min\" | \"max\" | \"countDistinct\";\n\nexport interface AnalyticsMeasure {\n type: MeasureType;\n /** SQL column or expression (e.g., \"grand_total\" or \"quantity_on_hand * COALESCE(unit_cost, 0)\") */\n sql?: string | undefined;\n /** SQL filter expression that must be true for this measure to count a row */\n filter?: string | undefined;\n}\n\nexport type DimensionType = \"string\" | \"number\" | \"time\" | \"boolean\";\n\nexport interface AnalyticsDimension {\n /** SQL column or expression */\n sql: string;\n type: DimensionType;\n}\n\nexport interface AnalyticsJoin {\n table: string;\n type: \"left\" | \"inner\";\n on: string;\n}\n\nexport interface AnalyticsModel {\n name: string;\n table: string;\n joins?: AnalyticsJoin[];\n measures: Record<string, AnalyticsMeasure>;\n dimensions: Record<string, AnalyticsDimension>;\n segments?: Record<string, { sql: string }>;\n /**\n * Scope rules define how this model is filtered by role.\n * The filter SQL uses :vendorId or :customerId as placeholders.\n *\n * Example: { role: \"vendor\", filter: \"vendor_id = :vendorId\" }\n */\n scopeRules?: AnalyticsScopeRule[];\n}\n\n// ─── Scope (Role-Based Query Filtering) ──────────────────────────────────────\n\nexport interface AnalyticsScope {\n role: \"admin\" | \"staff\" | \"vendor\" | \"customer\" | \"public\";\n vendorId?: string | undefined;\n customerId?: string | undefined;\n}\n\n/**\n * Scope rule: defines how an analytics model is filtered for a given role.\n * Registered alongside model definitions.\n */\nexport interface AnalyticsScopeRule {\n /** Which role this rule applies to */\n role: \"vendor\" | \"customer\";\n /** SQL WHERE clause fragment. Use :vendorId or :customerId as placeholders. */\n filter: string;\n}\n\n// ─── Scope Builder ───────────────────────────────────────────────────────────\n\n/**\n * Build an AnalyticsScope from an actor (or null for public).\n *\n * This is the ONLY way scopes should be created. Every call site that\n * invokes analytics.query() MUST use this function — never construct\n * a scope manually. This ensures the scope always reflects the\n * authenticated actor's actual role and identity.\n */\nexport function buildAnalyticsScope(actor: {\n role?: string;\n vendorId?: string | null;\n userId?: string;\n} | null): AnalyticsScope {\n if (!actor) return { role: \"public\" };\n\n const role = actor.role ?? \"public\";\n\n if (role === \"admin\" || role === \"owner\" || role === \"staff\" || role === \"ai_agent\") {\n return { role: \"admin\" };\n }\n\n if (actor.vendorId) {\n return { role: \"vendor\", vendorId: actor.vendorId };\n }\n\n if (role === \"customer\" && actor.userId) {\n return { role: \"customer\", customerId: actor.userId };\n }\n\n // Unknown role — deny access\n return { role: \"public\" };\n}\n\n// ─── Adapter Interface ───────────────────────────────────────────────────────\n\nexport interface AnalyticsAdapter {\n /** Scope is REQUIRED. Use buildAnalyticsScope(actor) to construct it. */\n query(params: AnalyticsQueryParams, scope: AnalyticsScope): Promise<Result<AnalyticsQueryResult>>;\n getMeta(scope: AnalyticsScope): Promise<Result<AnalyticsMeta>>;\n registerModel(model: AnalyticsModel): void;\n}\n\n// ─── Deprecated aliases (remove in next major version) ──────────────────────\n\n/** @deprecated Use AnalyticsModel instead */\nexport type CubeDefinition = AnalyticsModel;\n/** @deprecated Use AnalyticsScopeRule instead */\nexport type CubeScopeRule = AnalyticsScopeRule;\n/** @deprecated Use AnalyticsMeasure instead */\nexport type MeasureDefinition = AnalyticsMeasure;\n/** @deprecated Use AnalyticsDimension instead */\nexport type DimensionDefinition = AnalyticsDimension;\n/** @deprecated Use AnalyticsJoin instead */\nexport type JoinDefinition = AnalyticsJoin;\n",
|
|
39
|
+
"import { CommerceInvalidTransitionError } from \"../errors\";\n\nexport interface StateDefinition<TState extends string> {\n states: readonly TState[];\n initial: TState;\n transitions: Record<TState, readonly TState[]>;\n terminal: readonly TState[];\n}\n\nexport type OrderState = string;\n\nconst DEFAULT_TRANSITIONS: Record<string, readonly string[]> = {\n pending: [\"confirmed\", \"cancelled\"],\n confirmed: [\"processing\", \"cancelled\"],\n processing: [\"partially_fulfilled\", \"fulfilled\", \"cancelled\"],\n partially_fulfilled: [\"fulfilled\", \"cancelled\"],\n fulfilled: [\"refunded\"],\n cancelled: [],\n refunded: [],\n};\n\nconst DEFAULT_STATES: readonly string[] = [\n \"pending\", \"confirmed\", \"processing\", \"partially_fulfilled\",\n \"fulfilled\", \"cancelled\", \"refunded\",\n];\n\nconst DEFAULT_TERMINAL: readonly string[] = [\"cancelled\", \"refunded\"];\n\nexport const orderStateMachine: StateDefinition<string> = {\n states: DEFAULT_STATES,\n initial: \"pending\",\n transitions: DEFAULT_TRANSITIONS,\n terminal: DEFAULT_TERMINAL,\n};\n\n/**\n * Extend the order state machine with custom transitions.\n * New states are added automatically. Existing state transition arrays\n * are merged (union, not replaced) with the custom ones.\n *\n * Usage:\n * const extended = extendOrderStateMachine({\n * pending: [\"payment_initiated\"],\n * payment_initiated: [\"payment_authorized\", \"payment_failed\"],\n * payment_authorized: [\"processing\"],\n * });\n */\nexport function extendOrderStateMachine(\n customTransitions: Record<string, string[]>,\n): StateDefinition<string> {\n const merged: Record<string, string[]> = {};\n\n // Copy defaults\n for (const [state, targets] of Object.entries(DEFAULT_TRANSITIONS)) {\n merged[state] = [...targets];\n }\n\n // Merge custom\n for (const [state, targets] of Object.entries(customTransitions)) {\n if (!merged[state]) merged[state] = [];\n for (const t of targets) {\n if (!merged[state].includes(t)) merged[state].push(t);\n }\n // Ensure target states also exist in the map\n for (const t of targets) {\n if (!merged[t]) merged[t] = [];\n }\n }\n\n const allStates = Object.keys(merged);\n const terminal = allStates.filter((s) => merged[s]!.length === 0);\n\n return {\n states: allStates,\n initial: \"pending\",\n transitions: merged,\n terminal,\n };\n}\n\nexport function canTransition<TState extends string>(\n machine: StateDefinition<TState>,\n from: TState,\n to: TState,\n): boolean {\n return machine.transitions[from].includes(to);\n}\n\nexport function assertTransition<TState extends string>(\n machine: StateDefinition<TState>,\n from: TState,\n to: TState,\n): void {\n if (!canTransition(machine, from, to)) {\n throw new CommerceInvalidTransitionError(\n `Cannot transition from \"${from}\" to \"${to}\". Allowed transitions from \"${from}\": [${machine.transitions[\n from\n ].join(\", \")}]`,\n );\n }\n}\n",
|
|
40
|
+
"import { orderStateMachine } from \"../../kernel/state-machine/machine\";\nimport type { Order, OrderLineItem } from \"../../modules/orders/repository\";\nimport type { Kernel } from \"../../runtime/kernel\";\n\nfunction getAvailableTransitions(status: string): string[] {\n const transitions = (\n orderStateMachine.transitions as Record<string, readonly string[]>\n )[status];\n return transitions ? [...transitions] : [];\n}\n\nasync function inventorySummary(\n kernel: Kernel,\n entityId: string,\n): Promise<{\n onHand: number;\n reserved: number;\n available: number;\n lowStock: boolean;\n reorderSuggestionUnits: number;\n}> {\n const result = await kernel.services.inventory.checkMultiple([entityId]);\n const available = result.ok ? (result.value[entityId] ?? 0) : 0;\n\n // For low stock detection, we need a simple heuristic since we don't have\n // direct access to all level details from service API. Use available <= 0.\n const lowStock = available <= 0;\n\n return {\n onHand: available, // approximation when detailed levels not available\n reserved: 0,\n available,\n lowStock,\n reorderSuggestionUnits: 0,\n };\n}\n\ninterface AgentQuery {\n tool: string;\n params: Record<string, unknown>;\n}\n\ntype Enriched<T> = T & {\n _context: {\n summary: string;\n relatedQueries: AgentQuery[];\n [key: string]: unknown;\n };\n};\n\ntype AgentOrder = Order & { lineItems: OrderLineItem[] };\n\nexport function enrichOrderForAgent(\n order: AgentOrder,\n permissions: string[],\n): Enriched<AgentOrder> {\n return {\n ...order,\n _context: {\n availableTransitions: getAvailableTransitions(order.status),\n permittedActions: permissions.filter((permission) =>\n [\"orders:update\", \"orders:read\", \"orders:cancel\"].includes(permission),\n ),\n summary: `Order ${order.orderNumber}: ${order.lineItems.reduce((sum, lineItem) => sum + lineItem.quantity, 0)} item(s) totaling ${order.grandTotal} ${order.currency}. Status: ${order.status}.`,\n relatedQueries: [\n {\n tool: \"inventory_check\",\n params: {\n entityIds: order.lineItems.map((lineItem) => lineItem.entityId),\n },\n },\n {\n tool: \"analytics_query\",\n params: {\n measures: [\"Orders.revenue\"],\n dimensions: [\"Orders.status\"],\n filters: [\n { member: \"Orders.id\", operator: \"equals\", values: [order.id] },\n ],\n },\n },\n ],\n },\n };\n}\n\n/**\n * Enriches an entity with contextual information for AI agents.\n * Accepts both SellableEntityRecord and Drizzle-inferred types.\n * Now async — uses kernel services instead of RuntimeState.\n */\nexport async function enrichEntityForAgent<\n T extends { id: string; slug: string },\n>(entity: T, kernel: Kernel): Promise<Enriched<T>> {\n const inventory = await inventorySummary(kernel, entity.id);\n\n // Get entity details with variants to count them\n const entityResult = await kernel.services.catalog.getById(entity.id, {\n includeVariants: true,\n });\n const variantCount =\n entityResult.ok && entityResult.value.variants\n ? entityResult.value.variants.length\n : 0;\n\n return {\n ...entity,\n _context: {\n summary: `${entity.slug} has ${variantCount} variant(s), ${inventory.available} available units.`,\n stockStatus: inventory.lowStock\n ? \"low\"\n : inventory.available > 0\n ? \"in_stock\"\n : \"out_of_stock\",\n variantCount,\n relatedQueries: [\n {\n tool: \"inventory_check\",\n params: { entityIds: [entity.id] },\n },\n {\n tool: \"analytics_query\",\n params: {\n measures: [\"OrderLineItems.itemsSold\"],\n dimensions: [\"OrderLineItems.title\"],\n filters: [\n {\n member: \"OrderLineItems.title\",\n operator: \"equals\",\n values: [entity.slug],\n },\n ],\n },\n },\n ],\n },\n };\n}\n\nexport function enrichInventoryForAgent(item: {\n entityId: string;\n available: number;\n reorderThreshold?: number | null;\n reorderQuantity?: number | null;\n}): Enriched<{\n entityId: string;\n available: number;\n reorderThreshold?: number | null;\n reorderQuantity?: number | null;\n}> {\n const lowStock =\n item.reorderThreshold != null\n ? item.available <= item.reorderThreshold\n : item.available <= 0;\n\n return {\n ...item,\n _context: {\n lowStockWarning: lowStock,\n reorderSuggestion:\n lowStock && item.reorderQuantity != null\n ? {\n suggestedUnits: item.reorderQuantity,\n }\n : null,\n summary: lowStock\n ? `Entity ${item.entityId} is low on stock (${item.available} available).`\n : `Entity ${item.entityId} has healthy stock (${item.available} available).`,\n relatedQueries: [\n {\n tool: \"catalog_search\",\n params: { query: item.entityId },\n },\n ],\n },\n };\n}\n",
|
|
41
|
+
"import type { MCPResource, MCPTool } from \"../../config/types\";\nimport type { AnalyticsQueryParams } from \"../../modules/analytics/service\";\nimport { buildAnalyticsScope } from \"../../modules/analytics/types\";\nimport type { Kernel } from \"../../runtime/kernel\";\nimport { orderStateMachine } from \"../../kernel/state-machine/machine\";\nimport {\n enrichEntityForAgent,\n enrichInventoryForAgent,\n enrichOrderForAgent,\n} from \"./context-enrichment\";\n\nfunction textContent(value: unknown) {\n return {\n content: [{ type: \"text\", text: JSON.stringify(value, null, 2) }],\n };\n}\n\nfunction asObject(params: unknown): Record<string, unknown> {\n if (!params || typeof params !== \"object\" || Array.isArray(params)) return {};\n return params as Record<string, unknown>;\n}\n\nfunction readString(\n params: Record<string, unknown>,\n key: string,\n): string | undefined {\n const value = params[key];\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction readNumber(\n params: Record<string, unknown>,\n key: string,\n): number | undefined {\n const value = params[key];\n return typeof value === \"number\" && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nfunction readStringArray(\n params: Record<string, unknown>,\n key: string,\n): string[] {\n const value = params[key];\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === \"string\");\n}\n\nfunction validationError(message: string): {\n error: { code: string; message: string };\n} {\n return {\n error: {\n code: \"VALIDATION_FAILED\",\n message,\n },\n };\n}\n\nexport function registerMCPCapabilities(kernel: Kernel): {\n tools: MCPTool[];\n resources: MCPResource[];\n} {\n return {\n tools: [\n {\n name: \"catalog_search\",\n description:\n \"Search the catalog. Filter by type, status, category, brand, price range, free-text. Returns paginated results with pricing and availability.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: { type: \"string\" },\n type: { type: \"string\" },\n status: { type: \"string\" },\n categorySlug: { type: \"string\" },\n brandSlug: { type: \"string\" },\n page: { type: \"number\", default: 1 },\n limit: { type: \"number\", default: 20 },\n },\n },\n handler: async (params: unknown) => {\n const input = asObject(params);\n const query = (readString(input, \"query\") ?? \"\").trim().toLowerCase();\n const page = readNumber(input, \"page\") ?? 1;\n const limit = readNumber(input, \"limit\") ?? 20;\n const type = readString(input, \"type\");\n const status = readString(input, \"status\");\n const categorySlug = readString(input, \"categorySlug\");\n const brandSlug = readString(input, \"brandSlug\");\n if (query.length > 0) {\n const searchResult = await kernel.services.search.query({\n query,\n page,\n limit,\n filters: {\n ...(type ? { type } : {}),\n ...(status ? { status } : {}),\n ...(categorySlug ? { category: categorySlug } : {}),\n ...(brandSlug ? { brand: brandSlug } : {}),\n },\n });\n\n if (!searchResult.ok) return { error: searchResult.error };\n\n const enrichedItems = await Promise.all(\n searchResult.value.hits.map(async (hit) => {\n const entityResult = await kernel.services.catalog.getById(\n hit.id,\n );\n if (entityResult.ok) {\n return enrichEntityForAgent(entityResult.value, kernel);\n }\n return hit.document;\n }),\n );\n\n return textContent({\n items: await Promise.all(enrichedItems),\n pagination: {\n page: searchResult.value.page,\n limit: searchResult.value.limit,\n total: searchResult.value.total,\n totalPages: Math.max(\n 1,\n Math.ceil(\n searchResult.value.total / searchResult.value.limit,\n ),\n ),\n },\n facets: searchResult.value.facets,\n });\n }\n\n const result = await kernel.services.catalog.list({\n filter: {\n ...(type ? { type } : {}),\n ...(status ? { status } : {}),\n ...(categorySlug ? { category: categorySlug } : {}),\n ...(brandSlug ? { brand: brandSlug } : {}),\n },\n pagination: {\n page,\n limit,\n },\n });\n if (!result.ok) return { error: result.error };\n\n return textContent({\n ...result.value,\n items: await Promise.all(\n result.value.items.map((item) =>\n enrichEntityForAgent(item, kernel),\n ),\n ),\n });\n },\n },\n {\n name: \"catalog_create_entity\",\n description:\n \"Create a new catalog entity. Requires type, slug, title. Created in draft status.\",\n inputSchema: {\n type: \"object\",\n required: [\"type\", \"slug\", \"title\"],\n properties: {\n type: { type: \"string\" },\n slug: { type: \"string\" },\n title: { type: \"string\" },\n description: { type: \"string\" },\n metadata: { type: \"object\" },\n },\n },\n handler: async (params: unknown) => {\n const input = asObject(params);\n const type = readString(input, \"type\");\n const slug = readString(input, \"slug\");\n const title = readString(input, \"title\");\n const description = readString(input, \"description\");\n if (!type || !slug || !title) {\n return validationError(\"type, slug, and title are required.\");\n }\n const result = await kernel.services.catalog.create(\n {\n type,\n slug,\n attributes: {\n locale: \"en\",\n title,\n ...(description !== undefined ? { description } : {}),\n },\n ...(input.metadata &&\n typeof input.metadata === \"object\" &&\n !Array.isArray(input.metadata)\n ? { metadata: input.metadata as Record<string, unknown> }\n : {}),\n },\n kernel.getMCPActor(),\n );\n\n if (!result.ok) return { error: result.error };\n return textContent(await enrichEntityForAgent(result.value, kernel));\n },\n },\n {\n name: \"inventory_check\",\n description: \"Check stock levels for one or more entities/variants.\",\n inputSchema: {\n type: \"object\",\n required: [\"entityIds\"],\n properties: {\n entityIds: {\n type: \"array\",\n items: { type: \"string\" },\n },\n },\n },\n handler: async (params: unknown) => {\n const input = asObject(params);\n const entityIds = readStringArray(input, \"entityIds\");\n if (entityIds.length === 0) {\n return validationError(\"entityIds is required.\");\n }\n const result =\n await kernel.services.inventory.checkMultiple(entityIds);\n if (!result.ok) return { error: result.error };\n\n const enriched = await Promise.all(\n Object.entries(result.value).map(async ([entityId, available]) => {\n const levelsResult =\n await kernel.services.inventory.getLevelsByEntityId(entityId);\n const levels = levelsResult.ok ? levelsResult.value : [];\n const reorderThreshold = levels[0]?.reorderThreshold;\n const reorderQuantity = levels[0]?.reorderQuantity;\n\n return enrichInventoryForAgent({\n entityId,\n available,\n ...(reorderThreshold !== undefined ? { reorderThreshold } : {}),\n ...(reorderQuantity !== undefined ? { reorderQuantity } : {}),\n });\n }),\n );\n\n return textContent(enriched);\n },\n },\n {\n name: \"inventory_adjust\",\n description:\n \"Adjust inventory. Positive adds stock, negative removes. Requires reason.\",\n inputSchema: {\n type: \"object\",\n required: [\"entityId\", \"adjustment\", \"reason\"],\n properties: {\n entityId: { type: \"string\" },\n variantId: { type: \"string\" },\n adjustment: { type: \"number\" },\n reason: { type: \"string\" },\n },\n },\n handler: async (params: unknown) => {\n const input = asObject(params);\n const entityId = readString(input, \"entityId\");\n const adjustment = readNumber(input, \"adjustment\");\n const reason = readString(input, \"reason\");\n const variantId = readString(input, \"variantId\");\n if (!entityId || adjustment === undefined || !reason) {\n return validationError(\n \"entityId, adjustment, and reason are required.\",\n );\n }\n\n const result = await kernel.services.inventory.adjust(\n {\n entityId,\n adjustment,\n reason,\n ...(variantId !== undefined ? { variantId } : {}),\n },\n kernel.getMCPActor(),\n );\n if (!result.ok) return { error: result.error };\n\n const availableResult = await kernel.services.inventory.getAvailable(\n entityId,\n variantId,\n );\n\n return textContent(\n enrichInventoryForAgent({\n entityId,\n available: availableResult.ok ? availableResult.value : 0,\n ...(result.value.reorderThreshold !== undefined\n ? { reorderThreshold: result.value.reorderThreshold }\n : {}),\n ...(result.value.reorderQuantity !== undefined\n ? { reorderQuantity: result.value.reorderQuantity }\n : {}),\n }),\n );\n },\n },\n {\n name: \"cart_create\",\n description:\n \"Create a new shopping cart. Returns cart ID for subsequent operations.\",\n inputSchema: {\n type: \"object\",\n properties: {\n customerId: { type: \"string\" },\n currency: { type: \"string\", default: \"USD\" },\n },\n },\n handler: async (params: unknown) => {\n const input = asObject(params);\n const customerId = readString(input, \"customerId\");\n const currency = readString(input, \"currency\");\n const result = await kernel.services.cart.create(\n {\n ...(customerId !== undefined ? { customerId } : {}),\n ...(currency !== undefined ? { currency } : {}),\n },\n kernel.getMCPActor(),\n );\n if (!result.ok) return { error: result.error };\n return textContent(result.value);\n },\n },\n {\n name: \"cart_add_item\",\n description:\n \"Add item to cart. If entity has variants and no variantId provided, fails with available variants.\",\n inputSchema: {\n type: \"object\",\n required: [\"cartId\", \"entityId\"],\n properties: {\n cartId: { type: \"string\" },\n entityId: { type: \"string\" },\n variantId: { type: \"string\" },\n quantity: { type: \"number\", default: 1 },\n },\n },\n handler: async (params: unknown) => {\n const input = asObject(params);\n const cartId = readString(input, \"cartId\");\n const entityId = readString(input, \"entityId\");\n const variantId = readString(input, \"variantId\");\n const quantity = readNumber(input, \"quantity\");\n if (!cartId || !entityId) {\n return validationError(\"cartId and entityId are required.\");\n }\n const result = await kernel.services.cart.addItem(\n {\n cartId,\n entityId,\n ...(variantId !== undefined ? { variantId } : {}),\n quantity: quantity ?? 1,\n },\n kernel.getMCPActor(),\n );\n if (!result.ok) return { error: result.error };\n return textContent(result.value);\n },\n },\n {\n name: \"order_get\",\n description:\n \"Get order details by ID or order number. Includes line items, payment, fulfillment, and AI context.\",\n inputSchema: {\n type: \"object\",\n properties: {\n orderId: { type: \"string\" },\n orderNumber: { type: \"string\" },\n },\n },\n handler: async (params: unknown) => {\n const input = asObject(params);\n const orderId = readString(input, \"orderId\");\n const orderNumber = readString(input, \"orderNumber\");\n if (!orderId && !orderNumber) {\n return validationError(\n \"Either orderId or orderNumber is required.\",\n );\n }\n\n const result = orderId\n ? await kernel.services.orders.getById(\n orderId,\n kernel.getMCPActor(),\n )\n : await kernel.services.orders.getByNumber(\n orderNumber ?? \"\",\n kernel.getMCPActor(),\n );\n\n if (!result.ok) return { error: result.error };\n const enriched = enrichOrderForAgent(\n result.value,\n kernel.getMCPActor().permissions,\n );\n return textContent(enriched);\n },\n },\n {\n name: \"order_list\",\n description: \"List orders with pagination and optional status filter.\",\n inputSchema: {\n type: \"object\",\n properties: {\n page: { type: \"number\", default: 1 },\n limit: { type: \"number\", default: 20 },\n status: { type: \"string\" },\n },\n },\n handler: async (params: unknown) => {\n const input = asObject(params);\n const page = readNumber(input, \"page\");\n const limit = readNumber(input, \"limit\");\n const status = readString(input, \"status\");\n const result = await kernel.services.orders.list(\n {\n ...(page !== undefined ? { page } : {}),\n ...(limit !== undefined ? { limit } : {}),\n ...(status !== undefined ? { status } : {}),\n },\n kernel.getMCPActor(),\n );\n\n if (!result.ok) return { error: result.error };\n return textContent({\n ...result.value,\n items: result.value.items.map((order) =>\n enrichOrderForAgent(order, kernel.getMCPActor().permissions),\n ),\n });\n },\n },\n {\n name: \"analytics_query\",\n description:\n \"Query analytics using semantic measures, dimensions, time dimensions, and filters.\",\n inputSchema: {\n type: \"object\",\n required: [\"measures\"],\n properties: {\n measures: {\n type: \"array\",\n items: { type: \"string\" },\n },\n dimensions: {\n type: \"array\",\n items: { type: \"string\" },\n },\n timeDimensions: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n dimension: { type: \"string\" },\n granularity: {\n type: \"string\",\n enum: [\"day\", \"week\", \"month\", \"year\"],\n },\n dateRange: {\n oneOf: [\n { type: \"string\" },\n {\n type: \"array\",\n items: { type: \"string\" },\n minItems: 2,\n maxItems: 2,\n },\n ],\n },\n },\n required: [\"dimension\"],\n },\n },\n filters: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n member: { type: \"string\" },\n operator: {\n type: \"string\",\n enum: [\n \"equals\",\n \"notEquals\",\n \"contains\",\n \"in\",\n \"notIn\",\n \"gt\",\n \"gte\",\n \"lt\",\n \"lte\",\n \"beforeDate\",\n \"afterDate\",\n \"inDateRange\",\n ],\n },\n values: {\n type: \"array\",\n items: { type: \"string\" },\n },\n },\n required: [\"member\", \"operator\"],\n },\n },\n order: {\n type: \"object\",\n additionalProperties: {\n type: \"string\",\n enum: [\"asc\", \"desc\"],\n },\n },\n limit: { type: \"number\", default: 100 },\n },\n },\n handler: async (params: unknown) => {\n const input = asObject(params);\n const measures = readStringArray(input, \"measures\");\n const limit = readNumber(input, \"limit\");\n if (measures.length === 0) {\n return validationError(\"measures is required.\");\n }\n\n const queryParams: AnalyticsQueryParams = {\n measures,\n ...(Array.isArray(input.dimensions)\n ? {\n dimensions: input.dimensions.filter(\n (item): item is string => typeof item === \"string\",\n ),\n }\n : {}),\n ...(Array.isArray(input.timeDimensions)\n ? {\n timeDimensions: input.timeDimensions as NonNullable<\n AnalyticsQueryParams[\"timeDimensions\"]\n >,\n }\n : {}),\n ...(Array.isArray(input.filters)\n ? {\n filters: input.filters as NonNullable<\n AnalyticsQueryParams[\"filters\"]\n >,\n }\n : {}),\n ...(input.order &&\n typeof input.order === \"object\" &&\n !Array.isArray(input.order)\n ? {\n order: input.order as NonNullable<\n AnalyticsQueryParams[\"order\"]\n >,\n }\n : {}),\n ...(limit !== undefined ? { limit } : {}),\n };\n\n // Scope is always derived from the actor — never manually constructed.\n const analyticsScope = buildAnalyticsScope(kernel.getMCPActor());\n\n const result = await kernel.services.analytics.query(queryParams, analyticsScope);\n if (!result.ok) return { error: result.error };\n return textContent(result.value);\n },\n },\n {\n name: \"analytics_meta\",\n description:\n \"List available analytics measures, dimensions, segments, and models.\",\n inputSchema: {\n type: \"object\",\n },\n handler: async () => {\n const metaScope = buildAnalyticsScope(kernel.getMCPActor());\n const result = await kernel.services.analytics.getMeta();\n if (!result.ok) return { error: result.error };\n return textContent(result.value);\n },\n },\n ],\n resources: [\n {\n uri: \"commerce://schema/entity-types\",\n name: \"Entity Type Schema\",\n description:\n \"Complete schema of all entity types, fields, variants, fulfillment strategies.\",\n mimeType: \"application/json\",\n handler: async () => ({\n content: [\n {\n type: \"text\",\n text: JSON.stringify(kernel.config.entities ?? {}, null, 2),\n },\n ],\n }),\n },\n {\n uri: \"commerce://schema/order-states\",\n name: \"Order State Machine\",\n description: \"All order states and valid transitions.\",\n mimeType: \"application/json\",\n handler: async () => ({\n content: [\n { type: \"text\", text: JSON.stringify(orderStateMachine, null, 2) },\n ],\n }),\n },\n ],\n };\n}\n",
|
|
42
|
+
"import { OpenAPIHono } from \"@hono/zod-openapi\";\nimport { swaggerUI } from \"@hono/swagger-ui\";\nimport { sql } from \"drizzle-orm\";\nimport type { Kernel } from \"../../runtime/kernel\";\nimport type { AppEnv } from \"./utils\";\nimport { catalogRoutes } from \"./routes/catalog\";\nimport { inventoryRoutes } from \"./routes/inventory\";\nimport { mediaRoutes } from \"./routes/media\";\nimport { cartRoutes } from \"./routes/carts\";\nimport { checkoutRoutes } from \"./routes/checkout\";\nimport { orderRoutes } from \"./routes/orders\";\nimport { paymentRoutes } from \"./routes/payments\";\nimport { webhookRoutes } from \"./routes/webhooks\";\nimport { pricingRoutes } from \"./routes/pricing\";\nimport { promotionRoutes } from \"./routes/promotions\";\nimport { searchRoutes } from \"./routes/search\";\nimport { auditRoutes } from \"./routes/audit\";\nimport { adminJobRoutes } from \"./routes/admin-jobs\";\n\nexport function createRestRoutes(kernel: Kernel) {\n const router = new OpenAPIHono<AppEnv>({\n // Standardize Zod validation error responses across all routes\n defaultHook: (result, c) => {\n if (!result.success) {\n const isProd = process.env.NODE_ENV === \"production\";\n return c.json({\n error: {\n code: \"VALIDATION_FAILED\",\n // In production: generic message. In dev: detailed field errors.\n message: isProd\n ? \"Invalid input.\"\n : result.error.issues\n .map((i) => `${i.path.join(\".\")}: ${i.message}`)\n .join(\"; \"),\n },\n }, 422);\n }\n },\n });\n\n // F5: Health check with database probe — minimal info for load balancers\n router.get(\"/health\", async (c) => {\n try {\n const db = kernel.database.db;\n await (db as { execute: (q: unknown) => Promise<unknown> }).execute(sql`SELECT 1`);\n return c.json({ status: \"ok\" });\n } catch {\n return c.json({ status: \"down\" }, 503);\n }\n });\n\n // ─── Domain routes ──────────────────────────────────────────────────\n router.route(\"/catalog\", catalogRoutes(kernel));\n router.route(\"/inventory\", inventoryRoutes(kernel));\n router.route(\"/media\", mediaRoutes(kernel));\n router.route(\"/carts\", cartRoutes(kernel));\n router.route(\"/checkout\", checkoutRoutes(kernel));\n router.route(\"/orders\", orderRoutes(kernel));\n router.route(\"/payments\", paymentRoutes(kernel));\n router.route(\"/webhooks\", webhookRoutes(kernel));\n router.route(\"/pricing\", pricingRoutes(kernel));\n router.route(\"/promotions\", promotionRoutes(kernel));\n router.route(\"/search\", searchRoutes(kernel));\n router.route(\"/audit\", auditRoutes(kernel));\n router.route(\"/admin\", adminJobRoutes(kernel));\n\n // Swagger UI — disabled in production unless config.exposeOpenApiSpec is true\n const exposeSpec = kernel.config.exposeOpenApiSpec ?? (process.env.NODE_ENV !== \"production\");\n if (exposeSpec) {\n router.get(\"/reference\", swaggerUI({ url: \"/api/doc\" }));\n }\n\n return router;\n}\n",
|
|
43
|
+
"import { OpenAPIHono } from \"@hono/zod-openapi\";\nimport type { Kernel } from \"../../../runtime/kernel\";\nimport type {\n CreateEntityInput,\n UpdateEntityInput,\n CreateCategoryInput,\n UpdateCategoryInput,\n CreateBrandInput,\n UpdateBrandInput,\n CreateOptionTypeInput,\n CreateOptionValueInput,\n CreateVariantInput,\n} from \"../../../modules/catalog/schemas\";\nimport type {\n SetAttributesInput,\n VariantGenerationStrategy,\n} from \"../../../modules/catalog/service\";\nimport {\n listEntitiesRoute,\n getEntityRoute,\n getEntityAttributesRoute,\n listCategoriesRoute,\n listBrandsRoute,\n deleteEntityRoute,\n deleteCategoryRoute,\n deleteBrandRoute,\n removeEntityFromCategoryRoute,\n removeEntityFromBrandRoute,\n publishEntityRoute,\n archiveEntityRoute,\n discontinueEntityRoute,\n addEntityToCategoryRoute,\n addEntityToBrandRoute,\n createEntityRoute,\n updateEntityRoute,\n setEntityAttributesRoute,\n createCategoryRoute,\n updateCategoryRoute,\n createBrandRoute,\n updateBrandRoute,\n createOptionTypeRoute,\n createOptionValueRoute,\n createVariantRoute,\n generateVariantsRoute,\n} from \"../schemas/catalog\";\nimport {\n type AppEnv,\n mapErrorToResponse,\n mapErrorToStatus,\n parseInclude,\n parsePagination,\n parseSort,\n} from \"../utils\";\n\nexport function catalogRoutes(kernel: Kernel) {\n const router = new OpenAPIHono<AppEnv>();\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(listEntitiesRoute, async (c) => {\n const include = parseInclude(c.req.query(\"include\"));\n const pagination = parsePagination(c.req.query());\n const filter: Record<string, string> = {};\n const type = c.req.query(\"type\");\n const status = c.req.query(\"status\");\n const category = c.req.query(\"category\");\n const brand = c.req.query(\"brand\");\n if (type) filter.type = type;\n if (status) filter.status = status;\n if (category) filter.category = category;\n if (brand) filter.brand = brand;\n\n const payload: Record<string, unknown> = {\n filter,\n pagination,\n };\n const sort = parseSort(c.req.query(\"sort\"));\n if (sort) payload.sort = sort;\n\n const result = await kernel.services.catalog.list(payload, c.get(\"actor\"));\n\n if (!result.ok) {\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n }\n\n let withIncludes = result.value.items;\n if (include.size > 0) {\n const includeOptions = {\n includeAttributes: include.has(\"attributes\"),\n includeVariants: include.has(\"variants\"),\n includeOptionTypes: include.has(\"optionTypes\"),\n includeCategories: include.has(\"categories\"),\n includeBrands: include.has(\"brands\"),\n includeMedia: include.has(\"media\"),\n includeInventory: include.has(\"inventory\"),\n includePricing: include.has(\"pricing\"),\n };\n const hydrated = await Promise.all(\n result.value.items.map(async (item) => {\n const full = await kernel.services.catalog.getById(\n item.id,\n includeOptions,\n );\n return full.ok ? full.value : item;\n }),\n );\n withIncludes = hydrated;\n }\n\n return c.json({\n data: withIncludes,\n meta: {\n pagination: result.value.pagination,\n },\n });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(getEntityRoute, async (c) => {\n const idOrSlug = c.req.param(\"idOrSlug\");\n const include = parseInclude(c.req.query(\"include\"));\n\n const isUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(idOrSlug);\n\n const includeOptions = {\n includeAttributes: include.has(\"attributes\"),\n includeVariants: include.has(\"variants\"),\n includeOptionTypes: include.has(\"optionTypes\"),\n includeCategories: include.has(\"categories\"),\n includeBrands: include.has(\"brands\"),\n includeMedia: include.has(\"media\"),\n includeInventory: include.has(\"inventory\"),\n includePricing: include.has(\"pricing\"),\n };\n\n const actor = c.get(\"actor\");\n const result = isUUID\n ? await kernel.services.catalog.getById(idOrSlug, includeOptions, actor)\n : await kernel.services.catalog.getBySlug(idOrSlug, includeOptions, actor);\n\n if (!result.ok) {\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n }\n\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(createEntityRoute, async (c) => {\n const result = await kernel.services.catalog.create(\n c.req.valid(\"json\") as CreateEntityInput,\n c.get(\"actor\"),\n );\n if (!result.ok) {\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n }\n return c.json({ data: result.value }, 201);\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(updateEntityRoute, async (c) => {\n const result = await kernel.services.catalog.update(\n c.req.param(\"id\"),\n c.req.valid(\"json\") as UpdateEntityInput,\n c.get(\"actor\"),\n );\n if (!result.ok) {\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n }\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(deleteEntityRoute, async (c) => {\n const result = await kernel.services.catalog.delete(\n c.req.param(\"id\"),\n c.get(\"actor\"),\n );\n if (!result.ok) {\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n }\n return c.json({ data: { deleted: true } });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(publishEntityRoute, async (c) => {\n const result = await kernel.services.catalog.publish(\n c.req.param(\"id\"),\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(archiveEntityRoute, async (c) => {\n const result = await kernel.services.catalog.archive(\n c.req.param(\"id\"),\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(discontinueEntityRoute, async (c) => {\n const result = await kernel.services.catalog.discontinue(\n c.req.param(\"id\"),\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(setEntityAttributesRoute, async (c) => {\n const result = await kernel.services.catalog.setAttributes(\n c.req.param(\"id\"),\n c.req.param(\"locale\"),\n c.req.valid(\"json\") as unknown as SetAttributesInput, // Zod-validated; requires double-cast because SetAttributesInput has required fields\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: { updated: true } });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(getEntityAttributesRoute, async (c) => {\n const result = await kernel.services.catalog.getAttributes(\n c.req.param(\"id\"),\n c.req.param(\"locale\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(listCategoriesRoute, async (c) => {\n const result = await kernel.services.catalog.listCategories({ actor: c.get(\"actor\"), tx: null, requestId: \"\" });\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(createCategoryRoute, async (c) => {\n const result = await kernel.services.catalog.createCategory(\n c.req.valid(\"json\") as CreateCategoryInput,\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value }, 201);\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(updateCategoryRoute, async (c) => {\n const result = await kernel.services.catalog.updateCategory(\n c.req.param(\"categoryId\"),\n c.req.valid(\"json\") as UpdateCategoryInput,\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(deleteCategoryRoute, async (c) => {\n const result = await kernel.services.catalog.deleteCategory(\n c.req.param(\"categoryId\"),\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: { deleted: true } });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(addEntityToCategoryRoute, async (c) => {\n const result = await kernel.services.catalog.addToCategory(\n c.req.param(\"id\"),\n c.req.param(\"categoryId\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: { linked: true } });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(removeEntityFromCategoryRoute, async (c) => {\n const result = await kernel.services.catalog.removeFromCategory(\n c.req.param(\"id\"),\n c.req.param(\"categoryId\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: { unlinked: true } });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(listBrandsRoute, async (c) => {\n const result = await kernel.services.catalog.listBrands({ actor: c.get(\"actor\"), tx: null, requestId: \"\" });\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(createBrandRoute, async (c) => {\n const result = await kernel.services.catalog.createBrand(\n c.req.valid(\"json\") as CreateBrandInput,\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value }, 201);\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(updateBrandRoute, async (c) => {\n const result = await kernel.services.catalog.updateBrand(\n c.req.param(\"brandId\"),\n c.req.valid(\"json\") as UpdateBrandInput,\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(deleteBrandRoute, async (c) => {\n const result = await kernel.services.catalog.deleteBrand(\n c.req.param(\"brandId\"),\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: { deleted: true } });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(addEntityToBrandRoute, async (c) => {\n const result = await kernel.services.catalog.addToBrand(\n c.req.param(\"id\"),\n c.req.param(\"brandId\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: { linked: true } });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(removeEntityFromBrandRoute, async (c) => {\n const result = await kernel.services.catalog.removeFromBrand(\n c.req.param(\"id\"),\n c.req.param(\"brandId\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: { unlinked: true } });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(createOptionTypeRoute, async (c) => {\n const result = await kernel.services.catalog.createOptionType(\n { ...(c.req.valid(\"json\") as Record<string, unknown>), entityId: c.req.param(\"id\") } as CreateOptionTypeInput,\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value }, 201);\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(createOptionValueRoute, async (c) => {\n const result = await kernel.services.catalog.createOptionValue(\n { ...(c.req.valid(\"json\") as Record<string, unknown>), optionTypeId: c.req.param(\"optionTypeId\") } as CreateOptionValueInput,\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value }, 201);\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(createVariantRoute, async (c) => {\n const result = await kernel.services.catalog.createVariant(\n { ...(c.req.valid(\"json\") as Record<string, unknown>), entityId: c.req.param(\"id\") } as CreateVariantInput,\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value }, 201);\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(generateVariantsRoute, async (c) => {\n const body = c.req.valid(\"json\") as VariantGenerationStrategy;\n const result = await kernel.services.catalog.generateVariants(\n c.req.param(\"id\"),\n body,\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value }, 201);\n });\n\n return router;\n}\n",
|
|
44
|
+
"import { z, createRoute } from \"@hono/zod-openapi\";\nimport { errorResponses } from \"./shared\";\nimport { CatalogEntityResponse, CatalogEntityListResponse } from \"./responses\";\nimport {\n CreateEntityBodySchema,\n UpdateEntityBodySchema,\n SetAttributesBodySchema,\n CreateCategoryBodySchema,\n UpdateCategoryBodySchema,\n CreateBrandBodySchema,\n UpdateBrandBodySchema,\n CreateOptionTypeBodySchema,\n CreateOptionValueBodySchema,\n CreateVariantBodySchema,\n GenerateVariantsBodySchema,\n} from \"../../../modules/catalog/schemas\";\n\n// ─── Response Schemas ───────────────────────────────────────────────────────\n\nconst DataResponse = CatalogEntityResponse;\nconst DataWithPaginationResponse = CatalogEntityListResponse;\n\n// ─── Path Params ────────────────────────────────────────────────────────────\n\nconst EntityIdOrSlugParam = z.object({\n idOrSlug: z.string().min(1).openapi({ example: \"my-product\" }),\n});\n\nconst EntityIdParam = z.object({\n id: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n});\n\nconst EntityIdLocaleParam = z.object({\n id: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n locale: z.string().min(1).openapi({ example: \"en\" }),\n});\n\nconst CategoryIdParam = z.object({\n categoryId: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n});\n\nconst BrandIdParam = z.object({\n brandId: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n});\n\nconst EntityCategoryParam = z.object({\n id: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n categoryId: z.uuid().openapi({ example: \"660e8400-e29b-41d4-a716-446655440000\" }),\n});\n\nconst EntityBrandParam = z.object({\n id: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n brandId: z.uuid().openapi({ example: \"660e8400-e29b-41d4-a716-446655440000\" }),\n});\n\n// ─── GET Route Definitions ─────────────────────────────────────────────────\n\nexport const listEntitiesRoute = createRoute({\n method: \"get\",\n path: \"/entities\",\n tags: [\"Catalog\"],\n summary: \"List catalog entities\",\n request: {\n query: z.object({\n type: z.string().optional(),\n status: z.string().optional(),\n category: z.string().optional(),\n brand: z.string().optional(),\n include: z.string().optional(),\n sort: z.string().optional(),\n page: z.string().optional(),\n limit: z.string().optional(),\n }),\n },\n responses: {\n 200: { content: { \"application/json\": { schema: DataWithPaginationResponse } }, description: \"Success\" },\n },\n});\n\nexport const getEntityRoute = createRoute({\n method: \"get\",\n path: \"/entities/{idOrSlug}\",\n tags: [\"Catalog\"],\n summary: \"Get a catalog entity by ID or slug\",\n request: {\n params: EntityIdOrSlugParam,\n query: z.object({ include: z.string().optional() }),\n },\n responses: {\n 200: { content: { \"application/json\": { schema: DataResponse } }, description: \"Success\" },\n ...errorResponses,\n },\n});\n\nexport const getEntityAttributesRoute = createRoute({\n method: \"get\",\n path: \"/entities/{id}/attributes/{locale}\",\n tags: [\"Catalog\"],\n summary: \"Get entity attributes for a locale\",\n request: { params: EntityIdLocaleParam },\n responses: {\n 200: { content: { \"application/json\": { schema: DataResponse } }, description: \"Success\" },\n ...errorResponses,\n },\n});\n\nexport const listCategoriesRoute = createRoute({\n method: \"get\",\n path: \"/categories\",\n tags: [\"Catalog\"],\n summary: \"List all categories\",\n responses: {\n 200: { content: { \"application/json\": { schema: DataResponse } }, description: \"Success\" },\n },\n});\n\nexport const listBrandsRoute = createRoute({\n method: \"get\",\n path: \"/brands\",\n tags: [\"Catalog\"],\n summary: \"List all brands\",\n responses: {\n 200: { content: { \"application/json\": { schema: DataResponse } }, description: \"Success\" },\n },\n});\n\n// ─── DELETE Route Definitions ──────────────────────────────────────────────\n\nexport const deleteEntityRoute = createRoute({\n method: \"delete\",\n path: \"/entities/{id}\",\n tags: [\"Catalog\"],\n summary: \"Delete a catalog entity\",\n request: { params: EntityIdParam },\n responses: {\n 200: { content: { \"application/json\": { schema: z.object({ data: z.object({ deleted: z.literal(true) }) }) } }, description: \"Deleted\" },\n ...errorResponses,\n },\n});\n\nexport const deleteCategoryRoute = createRoute({\n method: \"delete\",\n path: \"/categories/{categoryId}\",\n tags: [\"Catalog\"],\n summary: \"Delete a category\",\n request: { params: CategoryIdParam },\n responses: {\n 200: { content: { \"application/json\": { schema: z.object({ data: z.object({ deleted: z.literal(true) }) }) } }, description: \"Deleted\" },\n ...errorResponses,\n },\n});\n\nexport const deleteBrandRoute = createRoute({\n method: \"delete\",\n path: \"/brands/{brandId}\",\n tags: [\"Catalog\"],\n summary: \"Delete a brand\",\n request: { params: BrandIdParam },\n responses: {\n 200: { content: { \"application/json\": { schema: z.object({ data: z.object({ deleted: z.literal(true) }) }) } }, description: \"Deleted\" },\n ...errorResponses,\n },\n});\n\nexport const removeEntityFromCategoryRoute = createRoute({\n method: \"delete\",\n path: \"/entities/{id}/categories/{categoryId}\",\n tags: [\"Catalog\"],\n summary: \"Remove entity from category\",\n request: { params: EntityCategoryParam },\n responses: {\n 200: { content: { \"application/json\": { schema: z.object({ data: z.object({ unlinked: z.literal(true) }) }) } }, description: \"Unlinked\" },\n ...errorResponses,\n },\n});\n\nexport const removeEntityFromBrandRoute = createRoute({\n method: \"delete\",\n path: \"/entities/{id}/brands/{brandId}\",\n tags: [\"Catalog\"],\n summary: \"Remove entity from brand\",\n request: { params: EntityBrandParam },\n responses: {\n 200: { content: { \"application/json\": { schema: z.object({ data: z.object({ unlinked: z.literal(true) }) }) } }, description: \"Unlinked\" },\n ...errorResponses,\n },\n});\n\n// ─── No-body POST Route Definitions ────────────────────────────────────────\n\nexport const publishEntityRoute = createRoute({\n method: \"post\",\n path: \"/entities/{id}/publish\",\n tags: [\"Catalog\"],\n summary: \"Publish a catalog entity\",\n request: { params: EntityIdParam },\n responses: {\n 200: { content: { \"application/json\": { schema: DataResponse } }, description: \"Published\" },\n ...errorResponses,\n },\n});\n\nexport const archiveEntityRoute = createRoute({\n method: \"post\",\n path: \"/entities/{id}/archive\",\n tags: [\"Catalog\"],\n summary: \"Archive a catalog entity\",\n request: { params: EntityIdParam },\n responses: {\n 200: { content: { \"application/json\": { schema: DataResponse } }, description: \"Archived\" },\n ...errorResponses,\n },\n});\n\nexport const discontinueEntityRoute = createRoute({\n method: \"post\",\n path: \"/entities/{id}/discontinue\",\n tags: [\"Catalog\"],\n summary: \"Discontinue a catalog entity\",\n request: { params: EntityIdParam },\n responses: {\n 200: { content: { \"application/json\": { schema: DataResponse } }, description: \"Discontinued\" },\n ...errorResponses,\n },\n});\n\nexport const addEntityToCategoryRoute = createRoute({\n method: \"post\",\n path: \"/entities/{id}/categories/{categoryId}\",\n tags: [\"Catalog\"],\n summary: \"Add entity to a category\",\n request: { params: EntityCategoryParam },\n responses: {\n 200: { content: { \"application/json\": { schema: z.object({ data: z.object({ linked: z.literal(true) }) }) } }, description: \"Linked\" },\n ...errorResponses,\n },\n});\n\nexport const addEntityToBrandRoute = createRoute({\n method: \"post\",\n path: \"/entities/{id}/brands/{brandId}\",\n tags: [\"Catalog\"],\n summary: \"Add entity to a brand\",\n request: { params: EntityBrandParam },\n responses: {\n 200: { content: { \"application/json\": { schema: z.object({ data: z.object({ linked: z.literal(true) }) }) } }, description: \"Linked\" },\n ...errorResponses,\n },\n});\n\n// ─── Mutation Route Definitions ─────────────────────────────────────────────\n\nconst OptionTypeIdParam = z.object({\n optionTypeId: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n});\n\nexport const createEntityRoute = createRoute({\n method: \"post\",\n path: \"/entities\",\n tags: [\"Catalog\"],\n summary: \"Create a catalog entity\",\n request: {\n body: {\n content: { \"application/json\": { schema: CreateEntityBodySchema } },\n required: true,\n },\n },\n responses: {\n 201: { content: { \"application/json\": { schema: DataResponse } }, description: \"Created\" },\n ...errorResponses,\n },\n});\n\nexport const updateEntityRoute = createRoute({\n method: \"patch\",\n path: \"/entities/{id}\",\n tags: [\"Catalog\"],\n summary: \"Update a catalog entity\",\n request: {\n params: EntityIdParam,\n body: {\n content: { \"application/json\": { schema: UpdateEntityBodySchema } },\n required: true,\n },\n },\n responses: {\n 200: { content: { \"application/json\": { schema: DataResponse } }, description: \"Updated\" },\n ...errorResponses,\n },\n});\n\nexport const setEntityAttributesRoute = createRoute({\n method: \"put\",\n path: \"/entities/{id}/attributes/{locale}\",\n tags: [\"Catalog\"],\n summary: \"Set entity attributes for a locale\",\n request: {\n params: EntityIdLocaleParam,\n body: {\n content: { \"application/json\": { schema: SetAttributesBodySchema } },\n required: true,\n },\n },\n responses: {\n 200: { content: { \"application/json\": { schema: z.object({ data: z.object({ updated: z.literal(true) }) }) } }, description: \"Updated\" },\n ...errorResponses,\n },\n});\n\nexport const createCategoryRoute = createRoute({\n method: \"post\",\n path: \"/categories\",\n tags: [\"Catalog\"],\n summary: \"Create a category\",\n request: {\n body: {\n content: { \"application/json\": { schema: CreateCategoryBodySchema } },\n required: true,\n },\n },\n responses: {\n 201: { content: { \"application/json\": { schema: DataResponse } }, description: \"Created\" },\n ...errorResponses,\n },\n});\n\nexport const updateCategoryRoute = createRoute({\n method: \"patch\",\n path: \"/categories/{categoryId}\",\n tags: [\"Catalog\"],\n summary: \"Update a category\",\n request: {\n params: CategoryIdParam,\n body: {\n content: { \"application/json\": { schema: UpdateCategoryBodySchema } },\n required: true,\n },\n },\n responses: {\n 200: { content: { \"application/json\": { schema: DataResponse } }, description: \"Updated\" },\n ...errorResponses,\n },\n});\n\nexport const createBrandRoute = createRoute({\n method: \"post\",\n path: \"/brands\",\n tags: [\"Catalog\"],\n summary: \"Create a brand\",\n request: {\n body: {\n content: { \"application/json\": { schema: CreateBrandBodySchema } },\n required: true,\n },\n },\n responses: {\n 201: { content: { \"application/json\": { schema: DataResponse } }, description: \"Created\" },\n ...errorResponses,\n },\n});\n\nexport const updateBrandRoute = createRoute({\n method: \"patch\",\n path: \"/brands/{brandId}\",\n tags: [\"Catalog\"],\n summary: \"Update a brand\",\n request: {\n params: BrandIdParam,\n body: {\n content: { \"application/json\": { schema: UpdateBrandBodySchema } },\n required: true,\n },\n },\n responses: {\n 200: { content: { \"application/json\": { schema: DataResponse } }, description: \"Updated\" },\n ...errorResponses,\n },\n});\n\nexport const createOptionTypeRoute = createRoute({\n method: \"post\",\n path: \"/entities/{id}/options\",\n tags: [\"Catalog\"],\n summary: \"Create an option type for an entity\",\n request: {\n params: EntityIdParam,\n body: {\n content: { \"application/json\": { schema: CreateOptionTypeBodySchema } },\n required: true,\n },\n },\n responses: {\n 201: { content: { \"application/json\": { schema: DataResponse } }, description: \"Created\" },\n ...errorResponses,\n },\n});\n\nexport const createOptionValueRoute = createRoute({\n method: \"post\",\n path: \"/options/{optionTypeId}/values\",\n tags: [\"Catalog\"],\n summary: \"Create an option value\",\n request: {\n params: OptionTypeIdParam,\n body: {\n content: { \"application/json\": { schema: CreateOptionValueBodySchema } },\n required: true,\n },\n },\n responses: {\n 201: { content: { \"application/json\": { schema: DataResponse } }, description: \"Created\" },\n ...errorResponses,\n },\n});\n\nexport const createVariantRoute = createRoute({\n method: \"post\",\n path: \"/entities/{id}/variants\",\n tags: [\"Catalog\"],\n summary: \"Create a variant for an entity\",\n request: {\n params: EntityIdParam,\n body: {\n content: { \"application/json\": { schema: CreateVariantBodySchema } },\n required: true,\n },\n },\n responses: {\n 201: { content: { \"application/json\": { schema: DataResponse } }, description: \"Created\" },\n ...errorResponses,\n },\n});\n\nexport const generateVariantsRoute = createRoute({\n method: \"post\",\n path: \"/entities/{id}/variants/generate\",\n tags: [\"Catalog\"],\n summary: \"Generate variants from option combinations\",\n request: {\n params: EntityIdParam,\n body: {\n content: { \"application/json\": { schema: GenerateVariantsBodySchema } },\n required: true,\n },\n },\n responses: {\n 201: { content: { \"application/json\": { schema: DataResponse } }, description: \"Generated\" },\n ...errorResponses,\n },\n});\n",
|
|
45
|
+
"/**\n * Typed response schemas derived from Drizzle table definitions.\n *\n * Uses drizzle-zod's createSelectSchema() to generate Zod schemas that\n * match the exact database column types. These replace z.any() in route\n * response definitions, making the OpenAPI spec show real field names\n * and types instead of empty {}.\n */\n\nimport { createSelectSchema } from \"drizzle-zod\";\nimport { z } from \"@hono/zod-openapi\";\nimport { orders, orderLineItems } from \"../../../modules/orders/schema\";\nimport { carts, cartLineItems } from \"../../../modules/cart/schema\";\nimport { customers, customerAddresses } from \"../../../modules/customers/schema\";\nimport { sellableEntities } from \"../../../modules/catalog/schema\";\nimport { commerceJobs } from \"../../../kernel/jobs/schema\";\n\n// ─── Orders ──────────────────────────────────────────────────────────────────\n\nexport const OrderSchema = createSelectSchema(orders).openapi(\"Order\");\n\nexport const OrderLineItemSchema = createSelectSchema(orderLineItems).openapi(\"OrderLineItem\");\n\nexport const OrderWithItemsSchema = z.object({\n ...OrderSchema.shape,\n lineItems: z.array(OrderLineItemSchema).optional(),\n}).openapi(\"OrderWithItems\");\n\n// ─── Carts ───────────────────────────────────────────────────────────────────\n\nexport const CartSchema = createSelectSchema(carts).openapi(\"Cart\");\n\nexport const CartLineItemSchema = createSelectSchema(cartLineItems).openapi(\"CartLineItem\");\n\nexport const CartWithItemsSchema = z.object({\n ...CartSchema.shape,\n lineItems: z.array(CartLineItemSchema).optional(),\n}).openapi(\"CartWithItems\");\n\n// ─── Customers ───────────────────────────────────────────────────────────────\n\nexport const CustomerSchema = createSelectSchema(customers).openapi(\"Customer\");\n\nexport const CustomerAddressSchema = createSelectSchema(customerAddresses).openapi(\"CustomerAddress\");\n\n// ─── Catalog ─────────────────────────────────────────────────────────────────\n\nexport const CatalogEntitySchema = createSelectSchema(sellableEntities).openapi(\"CatalogEntity\");\n\n// ─── Jobs ────────────────────────────────────────────────────────────────────\n\nexport const JobSchema = createSelectSchema(commerceJobs).openapi(\"Job\");\n\n// ─── Wrapped Response Helpers ────────────────────────────────────────────────\n// These wrap a schema in { data: T } for consistent API response format.\n\nexport function dataResponse<T extends z.ZodType>(schema: T, name: string) {\n return z.object({ data: schema }).openapi(name);\n}\n\nexport function dataArrayResponse<T extends z.ZodType>(schema: T, name: string) {\n return z.object({ data: z.array(schema) }).openapi(name);\n}\n\nexport function paginatedResponse<T extends z.ZodType>(schema: T, name: string) {\n return z.object({\n data: z.array(schema),\n meta: z.object({\n page: z.number(),\n limit: z.number(),\n total: z.number().optional(),\n }).optional(),\n }).openapi(name);\n}\n\n// ─── Pre-built Response Schemas ──────────────────────────────────────────────\n\nexport const OrderResponse = dataResponse(OrderSchema, \"OrderResponse\");\nexport const OrderListResponse = paginatedResponse(OrderSchema, \"OrderListResponse\");\nexport const CartResponse = dataResponse(CartWithItemsSchema, \"CartResponse\");\nexport const CustomerResponse = dataResponse(CustomerSchema, \"CustomerResponse\");\nexport const CustomerAddressListResponse = dataArrayResponse(CustomerAddressSchema, \"CustomerAddressListResponse\");\nexport const CatalogEntityResponse = dataResponse(CatalogEntitySchema, \"CatalogEntityResponse\");\nexport const CatalogEntityListResponse = paginatedResponse(CatalogEntitySchema, \"CatalogEntityListResponse\");\nexport const JobListResponse = dataArrayResponse(JobSchema, \"JobListResponse\");\n",
|
|
46
|
+
"import { z } from \"@hono/zod-openapi\";\n\n// ─── Catalog Body Schemas (single source of truth) ──────────────────────────\n\nexport const CreateEntityBodySchema = z.object({\n type: z.string().openapi({ example: \"physicalGood\" }),\n slug: z.string().openapi({ example: \"my-product\" }),\n status: z.string().optional().openapi({ example: \"draft\" }),\n basePrice: z.number().optional().openapi({ example: 29.99 }),\n currency: z.string().optional().openapi({ example: \"USD\" }),\n metadata: z.record(z.string(), z.unknown()).optional().openapi({ example: { title: \"My Product\" } }),\n attributes: z.object({\n locale: z.string().optional(),\n title: z.string(),\n subtitle: z.string().optional(),\n description: z.string().optional(),\n richDescription: z.record(z.string(), z.unknown()).optional(),\n seoTitle: z.string().optional(),\n seoDescription: z.string().optional(),\n }).optional(),\n customFields: z.record(z.string(), z.unknown()).optional(),\n}).openapi(\"CreateEntityBody\");\n\nexport const UpdateEntityBodySchema = z.object({\n slug: z.string().optional(),\n status: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n isVisible: z.boolean().optional(),\n}).openapi(\"UpdateEntityBody\");\n\nexport const SetAttributesBodySchema = z.record(z.string(), z.unknown()).openapi(\"SetAttributesBody\");\n\nexport const CreateCategoryBodySchema = z.object({\n slug: z.string().openapi({ example: \"shoes\" }),\n parentId: z.uuid().optional(),\n sortOrder: z.number().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n}).openapi(\"CreateCategoryBody\");\n\nexport const UpdateCategoryBodySchema = z.object({\n slug: z.string().optional(),\n parentId: z.uuid().nullable().optional(),\n sortOrder: z.number().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n}).openapi(\"UpdateCategoryBody\");\n\nexport const CreateBrandBodySchema = z.object({\n slug: z.string().openapi({ example: \"nike\" }),\n displayName: z.string().openapi({ example: \"Nike\" }),\n metadata: z.record(z.string(), z.unknown()).optional(),\n}).openapi(\"CreateBrandBody\");\n\nexport const UpdateBrandBodySchema = z.object({\n slug: z.string().optional(),\n displayName: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n}).openapi(\"UpdateBrandBody\");\n\nexport const CreateOptionTypeBodySchema = z.object({\n name: z.string().openapi({ example: \"Color\" }),\n values: z.array(z.string()).optional().openapi({ example: [\"Red\", \"Blue\"] }),\n}).openapi(\"CreateOptionTypeBody\");\n\nexport const CreateOptionValueBodySchema = z.object({\n value: z.string().openapi({ example: \"Green\" }),\n}).openapi(\"CreateOptionValueBody\");\n\nexport const CreateVariantBodySchema = z.object({\n sku: z.string().optional().openapi({ example: \"SKU-001\" }),\n options: z.record(z.string(), z.string()).openapi({ example: { Color: \"Red\" } }),\n price: z.number().optional().openapi({ example: 34.99 }),\n}).openapi(\"CreateVariantBody\");\n\nexport const GenerateVariantsBodySchema = z.object({}).passthrough().openapi(\"GenerateVariantsBody\");\n\n// ─── Derived Input Types ─────────────────────────────────────────────────────\n\nexport type CreateEntityInput = z.infer<typeof CreateEntityBodySchema>;\n\nexport type UpdateEntityInput = z.infer<typeof UpdateEntityBodySchema>;\n\nexport type CreateCategoryInput = z.infer<typeof CreateCategoryBodySchema> & {\n id?: string;\n};\n\nexport type UpdateCategoryInput = z.infer<typeof UpdateCategoryBodySchema>;\n\nexport type CreateBrandInput = z.infer<typeof CreateBrandBodySchema> & {\n id?: string;\n};\n\nexport type UpdateBrandInput = z.infer<typeof UpdateBrandBodySchema>;\n\nexport type CreateOptionTypeInput = z.infer<typeof CreateOptionTypeBodySchema> & {\n entityId: string;\n};\n\nexport type CreateOptionValueInput = z.infer<typeof CreateOptionValueBodySchema> & {\n optionTypeId: string;\n};\n\nexport type CreateVariantInput = z.infer<typeof CreateVariantBodySchema> & {\n entityId: string;\n};\n",
|
|
47
|
+
"import { OpenAPIHono } from \"@hono/zod-openapi\";\nimport type { Kernel } from \"../../../runtime/kernel\";\nimport {\n inventoryAdjustRoute,\n inventoryReserveRoute,\n inventoryReleaseRoute,\n createWarehouseRoute,\n inventoryCheckRoute,\n listWarehousesRoute,\n} from \"../schemas/inventory\";\nimport { type AppEnv, mapErrorToResponse, mapErrorToStatus } from \"../utils\";\n\nexport function inventoryRoutes(kernel: Kernel) {\n const router = new OpenAPIHono<AppEnv>();\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(inventoryCheckRoute, async (c) => {\n const entityIds = (c.req.query(\"entityIds\") ?? \"\")\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean);\n\n const result = await kernel.services.inventory.checkMultiple(entityIds);\n if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(inventoryAdjustRoute, async (c) => {\n const body = c.req.valid(\"json\");\n const result = await kernel.services.inventory.adjust(body, c.get(\"actor\"));\n if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(inventoryReserveRoute, async (c) => {\n const body = c.req.valid(\"json\");\n const result = await kernel.services.inventory.reserve(body, c.get(\"actor\"));\n if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n return c.json({ data: { reserved: true } });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(inventoryReleaseRoute, async (c) => {\n const body = c.req.valid(\"json\");\n const result = await kernel.services.inventory.release(body, c.get(\"actor\"));\n if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n return c.json({ data: { released: true } });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(createWarehouseRoute, async (c) => {\n const body = c.req.valid(\"json\") as Parameters<typeof kernel.services.inventory.createWarehouse>[0];\n const actor = c.get(\"actor\");\n const result = await kernel.services.inventory.createWarehouse(body, actor);\n if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n return c.json({ data: result.value }, 201);\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(listWarehousesRoute, async (c) => {\n const actor = c.get(\"actor\");\n const result = await kernel.services.inventory.listWarehouses(actor);\n if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n return c.json({ data: result.value });\n });\n\n return router;\n}\n",
|
|
48
|
+
"import { z, createRoute } from \"@hono/zod-openapi\";\nimport { ErrorSchema, errorResponses } from \"./shared\";\n\n// ─── Request Schemas ─────────────────────────────────────────────────────────\n\nimport { InventoryAdjustBodySchema, InventoryReserveBodySchema, InventoryReleaseBodySchema } from \"../../../modules/inventory/schemas\";\nexport { InventoryAdjustBodySchema, InventoryReserveBodySchema, InventoryReleaseBodySchema };\n\nexport const CreateWarehouseBodySchema = z.object({\n name: z.string().openapi({ example: \"Main Warehouse\" }),\n code: z.string().optional().openapi({ example: \"WH-MAIN\" }),\n address: z.record(z.string(), z.unknown()).optional(),\n}).openapi(\"CreateWarehouseRequest\");\n\n// ─── Route Definitions ──────────────────────────────────────────────────────\n\nexport const inventoryCheckRoute = createRoute({\n method: \"get\",\n path: \"/check\",\n tags: [\"Inventory\"],\n summary: \"Check inventory for entities\",\n request: {\n query: z.object({\n entityIds: z.string().optional().openapi({ example: \"uuid1,uuid2\" }),\n }),\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: z.object({ data: z.record(z.string(), z.unknown()) }) } },\n description: \"Inventory levels\",\n },\n },\n});\n\nexport const listWarehousesRoute = createRoute({\n method: \"get\",\n path: \"/warehouses\",\n tags: [\"Inventory\"],\n summary: \"List all warehouses\",\n responses: {\n 200: {\n content: { \"application/json\": { schema: z.object({ data: z.record(z.string(), z.unknown()) }) } },\n description: \"Warehouses\",\n },\n },\n});\n\nexport const inventoryAdjustRoute = createRoute({\n method: \"post\",\n path: \"/adjust\",\n tags: [\"Inventory\"],\n summary: \"Adjust inventory levels\",\n description: \"Adjusts the on-hand quantity for a given entity/variant in a warehouse.\",\n request: {\n body: {\n content: {\n \"application/json\": { schema: InventoryAdjustBodySchema },\n },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: z.object({ data: z.record(z.string(), z.unknown()) }) } },\n description: \"Inventory adjusted.\",\n },\n ...errorResponses,\n },\n});\n\nexport const inventoryReserveRoute = createRoute({\n method: \"post\",\n path: \"/reserve\",\n tags: [\"Inventory\"],\n summary: \"Reserve inventory\",\n description: \"Reserves inventory quantity for an order.\",\n request: {\n body: {\n content: {\n \"application/json\": { schema: InventoryReserveBodySchema },\n },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: z.object({ data: z.object({ reserved: z.literal(true) }) }) } },\n description: \"Inventory reserved.\",\n },\n ...errorResponses,\n },\n});\n\nexport const inventoryReleaseRoute = createRoute({\n method: \"post\",\n path: \"/release\",\n tags: [\"Inventory\"],\n summary: \"Release reserved inventory\",\n description: \"Releases previously reserved inventory back to available stock.\",\n request: {\n body: {\n content: {\n \"application/json\": { schema: InventoryReleaseBodySchema },\n },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: z.object({ data: z.object({ released: z.literal(true) }) }) } },\n description: \"Inventory released.\",\n },\n ...errorResponses,\n },\n});\n\nexport const createWarehouseRoute = createRoute({\n method: \"post\",\n path: \"/warehouses\",\n tags: [\"Inventory\"],\n summary: \"Create a warehouse\",\n description: \"Creates a new warehouse for inventory management.\",\n request: {\n body: {\n content: {\n \"application/json\": { schema: CreateWarehouseBodySchema },\n },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { \"application/json\": { schema: z.object({ data: z.record(z.string(), z.unknown()) }) } },\n description: \"Warehouse created.\",\n },\n ...errorResponses,\n },\n});\n",
|
|
49
|
+
"import { z } from \"@hono/zod-openapi\";\n\n// ─── Zod Body Schemas (single source of truth) ─────────────────────────────\n\nexport const InventoryAdjustBodySchema = z.object({\n entityId: z.string().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n variantId: z.string().optional().openapi({ example: \"variant-uuid\" }),\n warehouseId: z.string().optional().openapi({ example: \"warehouse-uuid\" }),\n adjustment: z.number().int().refine((v) => v !== 0, { message: \"Adjustment cannot be zero\" }).openapi({ example: 10 }),\n reason: z.string().openapi({ example: \"Restock from supplier\" }),\n performedBy: z.string().optional(),\n referenceType: z.string().optional(),\n referenceId: z.string().optional(),\n}).openapi(\"InventoryAdjustRequest\");\n\nexport const InventoryReserveBodySchema = z.object({\n entityId: z.string().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n variantId: z.string().optional(),\n warehouseId: z.string().optional(),\n quantity: z.number().int().min(1).openapi({ example: 2 }),\n orderId: z.string().openapi({ example: \"order-uuid\" }),\n performedBy: z.string().optional(),\n}).openapi(\"InventoryReserveRequest\");\n\nexport const InventoryReleaseBodySchema = z.object({\n entityId: z.string().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n variantId: z.string().optional(),\n warehouseId: z.string().optional(),\n quantity: z.number().int().min(1).openapi({ example: 2 }),\n orderId: z.string().openapi({ example: \"order-uuid\" }),\n performedBy: z.string().optional(),\n}).openapi(\"InventoryReleaseRequest\");\n\n// ─── Derived Input Types ────────────────────────────────────────────────────\n\nexport type InventoryAdjustInput = z.infer<typeof InventoryAdjustBodySchema>;\nexport type InventoryReserveInput = z.infer<typeof InventoryReserveBodySchema>;\nexport type InventoryReleaseInput = z.infer<typeof InventoryReleaseBodySchema>;\n",
|
|
50
|
+
"import { OpenAPIHono } from \"@hono/zod-openapi\";\nimport type { Kernel } from \"../../../runtime/kernel\";\nimport type { AttachMediaInput } from \"../../../modules/media/service\";\nimport { attachMediaRoute, getMediaRoute, deleteMediaRoute } from \"../schemas/media\";\nimport { type AppEnv, mapErrorToResponse, mapErrorToStatus, requirePerm } from \"../utils\";\n\nexport function mediaRoutes(kernel: Kernel) {\n const router = new OpenAPIHono<AppEnv>();\n\n // Upload requires authentication + media:write permission\n router.use(\"/upload\", requirePerm(\"media:write\"));\n\n router.post(\"/upload\", async (c) => {\n const body = await c.req.parseBody();\n const file = body.file as File;\n\n if (!file) {\n return c.json({ error: { code: \"VALIDATION_FAILED\", message: \"file is required\" } }, 422);\n }\n\n const buffer = await file.arrayBuffer();\n const actor = c.get(\"actor\");\n const result = await kernel.services.media.upload({\n filename: file.name,\n contentType: file.type,\n data: buffer,\n alt: String(body.alt ?? \"\"),\n }, actor);\n\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n\n return c.json({ data: result.value }, 201);\n });\n\n router.openapi(getMediaRoute, async (c) => {\n const signed = c.req.query(\"signed\") === \"true\";\n\n // Signed URLs require authentication\n if (signed && !c.get(\"actor\")) {\n return c.json(\n { error: { code: \"UNAUTHORIZED\", message: \"Authentication required for signed URLs.\" } },\n 401,\n );\n }\n\n const result = signed\n ? await kernel.services.media.getSignedUrl(c.req.param(\"id\"))\n : await kernel.services.media.getUrl(c.req.param(\"id\"));\n\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n\n return c.redirect(result.value, 302);\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(deleteMediaRoute, async (c) => {\n const actor = c.get(\"actor\");\n if (!actor || (!actor.permissions.includes(\"media:write\") && !actor.permissions.includes(\"*:*\"))) {\n return c.json({ error: { code: \"FORBIDDEN\", message: \"media:write permission required.\" } }, 403);\n }\n const result = await kernel.services.media.delete(c.req.param(\"id\"));\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n return c.json({ data: { deleted: true } });\n });\n\n // Attach requires media:write\n router.use(\"/attach\", requirePerm(\"media:write\"));\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(attachMediaRoute, async (c) => {\n const body = c.req.valid(\"json\") as AttachMediaInput;\n const result = await kernel.services.media.attachToEntity(body);\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n return c.json({ data: { attached: true } }, 201);\n });\n\n return router;\n}\n",
|
|
51
|
+
"import { z, createRoute } from \"@hono/zod-openapi\";\nimport { ErrorSchema, errorResponses } from \"./shared\";\n\n// ─── Request Schema ──────────────────────────────────────────────────────────\n\nexport const AttachMediaBodySchema = z.object({\n mediaAssetId: z.string().openapi({ example: \"asset-uuid\" }),\n entityId: z.string().openapi({ example: \"product-uuid\" }),\n role: z.enum([\"primary\", \"gallery\", \"thumbnail\", \"video\", \"document\"]).openapi({ example: \"primary\" }),\n variantId: z.string().optional(),\n sortOrder: z.number().optional().openapi({ example: 0 }),\n}).openapi(\"AttachMediaRequest\");\n\n// ─── Route Definitions ──────────────────────────────────────────────────────\n\nexport const getMediaRoute = createRoute({\n method: \"get\",\n path: \"/{id}\",\n tags: [\"Media\"],\n summary: \"Get a media asset (redirects to URL)\",\n request: {\n params: z.object({\n id: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n }),\n query: z.object({\n signed: z.string().optional().openapi({ example: \"true\" }),\n }),\n },\n responses: {\n 302: { description: \"Redirect to media URL\" },\n ...errorResponses,\n },\n});\n\nexport const deleteMediaRoute = createRoute({\n method: \"delete\",\n path: \"/{id}\",\n tags: [\"Media\"],\n summary: \"Delete a media asset\",\n request: {\n params: z.object({\n id: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n }),\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: z.object({ data: z.object({ deleted: z.literal(true) }) }) } },\n description: \"Media deleted.\",\n },\n ...errorResponses,\n },\n});\n\nexport const attachMediaRoute = createRoute({\n method: \"post\",\n path: \"/attach\",\n tags: [\"Media\"],\n summary: \"Attach a media asset to an entity\",\n description: \"Links an uploaded media asset to a catalog entity (product, variant, etc.).\",\n request: {\n body: {\n content: {\n \"application/json\": { schema: AttachMediaBodySchema },\n },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { \"application/json\": { schema: z.object({ data: z.object({ attached: z.literal(true) }) }) } },\n description: \"Media attached to entity.\",\n },\n ...errorResponses,\n },\n});\n",
|
|
52
|
+
"import { OpenAPIHono } from \"@hono/zod-openapi\";\nimport type { Kernel } from \"../../../runtime/kernel\";\nimport type { CreateCartInput, AddCartItemInput } from \"../../../modules/cart/schemas\";\nimport { createCartRoute, addCartItemRoute, updateCartItemQuantityRoute, getCartRoute, removeCartItemRoute } from \"../schemas/carts\";\nimport { type AppEnv, mapErrorToResponse, mapErrorToStatus } from \"../utils\";\n\nexport function cartRoutes(kernel: Kernel) {\n const router = new OpenAPIHono<AppEnv>();\n\n // @ts-expect-error -- openapi() enforces strict response typing but our handler\n // returns union responses (201 | 400 | 422). The route definition documents the\n // contract; the handler returns dynamic status.\n router.openapi(createCartRoute, async (c) => {\n const actor = c.get(\"actor\");\n const result = await kernel.services.cart.create(c.req.valid(\"json\") as CreateCartInput, actor);\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value }, 201);\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(getCartRoute, async (c) => {\n const actor = c.get(\"actor\");\n const result = await kernel.services.cart.getById(c.req.param(\"id\"), actor);\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi() enforces strict response typing but our handler\n // returns union responses (201 | 400 | 422). The route definition documents the\n // contract; the handler returns dynamic status.\n router.openapi(addCartItemRoute, async (c) => {\n const result = await kernel.services.cart.addItem(\n { ...c.req.valid(\"json\"), cartId: c.req.param(\"id\") } as AddCartItemInput,\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value }, 201);\n });\n\n // @ts-expect-error -- openapi() enforces strict response typing but our handler\n // returns union responses (200 | 400 | 422). The route definition documents the\n // contract; the handler returns dynamic status.\n router.openapi(updateCartItemQuantityRoute, async (c) => {\n const body = c.req.valid(\"json\");\n const result = await kernel.services.cart.updateQuantity(\n {\n cartId: c.req.param(\"id\"),\n itemId: c.req.param(\"itemId\"),\n quantity: body.quantity,\n },\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(removeCartItemRoute, async (c) => {\n const result = await kernel.services.cart.removeItem(\n c.req.param(\"id\"),\n c.req.param(\"itemId\"),\n c.get(\"actor\"),\n );\n if (!result.ok)\n return c.json(\n mapErrorToResponse(result.error),\n mapErrorToStatus(result.error),\n );\n return c.json({ data: { deleted: true } });\n });\n\n return router;\n}\n",
|
|
53
|
+
"import { z, createRoute } from \"@hono/zod-openapi\";\nimport { ErrorSchema, errorResponses, UuidParamSchema, DeletedResponseSchema } from \"./shared\";\nimport { CartResponse } from \"./responses\";\nimport {\n CreateCartBodySchema,\n AddCartItemBodySchema,\n UpdateCartItemQuantityBodySchema,\n} from \"../../../modules/cart/schemas\";\n\nexport { CreateCartBodySchema, AddCartItemBodySchema, UpdateCartItemQuantityBodySchema };\n\n// ─── Response Schemas ───────────────────────────────────────────────────────\n\nexport const CartResponseSchema = CartResponse;\n\n// ─── Path Params ────────────────────────────────────────────────────────────\n\nconst CartIdParam = z.object({\n id: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n});\n\nconst CartItemParams = z.object({\n id: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n itemId: z.uuid().openapi({ example: \"660e8400-e29b-41d4-a716-446655440000\" }),\n});\n\n// ─── Route Definitions ──────────────────────────────────────────────────────\n\nexport const getCartRoute = createRoute({\n method: \"get\",\n path: \"/{id}\",\n tags: [\"Carts\"],\n summary: \"Get a cart by ID\",\n request: { params: CartIdParam },\n responses: {\n 200: {\n content: { \"application/json\": { schema: CartResponseSchema } },\n description: \"Cart retrieved.\",\n },\n ...errorResponses,\n },\n});\n\nexport const removeCartItemRoute = createRoute({\n method: \"delete\",\n path: \"/{id}/items/{itemId}\",\n tags: [\"Carts\"],\n summary: \"Remove an item from a cart\",\n request: { params: CartItemParams },\n responses: {\n 200: {\n content: { \"application/json\": { schema: DeletedResponseSchema } },\n description: \"Item removed.\",\n },\n ...errorResponses,\n },\n});\n\nexport const createCartRoute = createRoute({\n method: \"post\",\n path: \"/\",\n tags: [\"Carts\"],\n summary: \"Create a new cart\",\n request: {\n body: {\n content: {\n \"application/json\": { schema: CreateCartBodySchema },\n },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { \"application/json\": { schema: CartResponseSchema } },\n description: \"Cart created successfully.\",\n },\n ...errorResponses,\n },\n});\n\nexport const addCartItemRoute = createRoute({\n method: \"post\",\n path: \"/{id}/items\",\n tags: [\"Carts\"],\n summary: \"Add an item to a cart\",\n request: {\n params: CartIdParam,\n body: {\n content: {\n \"application/json\": { schema: AddCartItemBodySchema },\n },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { \"application/json\": { schema: CartResponseSchema } },\n description: \"Item added to cart.\",\n },\n ...errorResponses,\n },\n});\n\nexport const updateCartItemQuantityRoute = createRoute({\n method: \"patch\",\n path: \"/{id}/items/{itemId}\",\n tags: [\"Carts\"],\n summary: \"Update the quantity of a cart line item\",\n request: {\n params: CartItemParams,\n body: {\n content: {\n \"application/json\": { schema: UpdateCartItemQuantityBodySchema },\n },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: CartResponseSchema } },\n description: \"Cart item quantity updated.\",\n },\n ...errorResponses,\n },\n});\n",
|
|
54
|
+
"import { z } from \"@hono/zod-openapi\";\n\n// ─── Cart Body Schemas (single source of truth) ─────────────────────────────\n\nexport const CreateCartBodySchema = z.object({\n customerId: z.string().optional().openapi({ example: \"customer-uuid\" }),\n currency: z.string().length(3).optional().openapi({ example: \"USD\" }),\n}).openapi(\"CreateCartRequest\");\n\nexport const AddCartItemBodySchema = z.object({\n entityId: z.string().openapi({ example: \"product-uuid\" }),\n variantId: z.string().nullable().optional().openapi({ example: \"variant-uuid\" }),\n quantity: z.number().int().min(1).max(9999).openapi({ example: 1 }),\n}).openapi(\"AddCartItemRequest\");\n\nexport const UpdateCartItemQuantityBodySchema = z.object({\n quantity: z.number().int().min(1).max(9999).openapi({ example: 2 }),\n}).openapi(\"UpdateCartItemQuantityRequest\");\n\n// ─── Derived Input Types ─────────────────────────────────────────────────────\n\nexport type CreateCartInput = z.infer<typeof CreateCartBodySchema> & {\n metadata?: Record<string, unknown>;\n};\n\nexport type AddCartItemInput = z.infer<typeof AddCartItemBodySchema> & {\n cartId: string;\n unitPriceSnapshot?: number;\n currency?: string;\n metadata?: Record<string, unknown>;\n};\n\n/** Hand-written: all fields come from path params + body; schema only has quantity. */\nexport interface UpdateCartItemInput {\n cartId: string;\n itemId: string;\n quantity: number;\n}\n",
|
|
55
|
+
"import { OpenAPIHono } from \"@hono/zod-openapi\";\nimport type { Kernel } from \"../../../runtime/kernel\";\nimport { checkoutRoute } from \"../schemas/checkout\";\nimport {\n applyPromotionCodes,\n authorizePayment,\n calculateShipping,\n calculateTax,\n checkInventoryAvailability,\n completeCheckout,\n recordAnalyticsEvent,\n resolveCurrentPrices,\n validateCartNotEmpty,\n validatePaymentMethod,\n type CheckoutData,\n type OrderResult,\n} from \"../../../hooks/checkout\";\nimport { runAfterHooks, runBeforeHooks } from \"../../../kernel/hooks/executor\";\nimport { createHookContext } from \"../../../kernel/hooks/create-context\";\nimport type { AfterHook, BeforeHook, ServiceContainer } from \"../../../kernel/hooks/types\";\nimport { type AppEnv, mapErrorToResponse, mapErrorToStatus } from \"../utils\";\nimport { isCommerceError } from \"../../../kernel/errors\";\nimport { makeId } from \"../../../utils/id\";\nimport type { ShippingAddress } from \"../../../modules/shipping/calculator\";\n\nexport function checkoutRoutes(kernel: Kernel) {\n const router = new OpenAPIHono<AppEnv>();\n\n // @ts-expect-error -- openapi() enforces strict response typing but our handler\n // returns union responses (201 | 400 | 422). The route definition documents the\n // contract; the defaultHook handles Zod validation; the handler returns dynamic status.\n router.openapi(checkoutRoute, async (c) => {\n const body = c.req.valid(\"json\");\n\n const actor = c.get(\"actor\");\n const checkoutData: CheckoutData = {\n checkoutId: makeId(),\n cartId: body.cartId,\n currency: body.currency ?? \"USD\",\n paymentMethodId: body.paymentMethodId,\n lineItems: [],\n subtotal: 0,\n discountTotal: 0,\n taxTotal: 0,\n shippingTotal: 0,\n total: 0,\n ...(body.customerId !== undefined ? { customerId: body.customerId } : {}),\n ...(body.customerGroupIds !== undefined\n ? { customerGroupIds: body.customerGroupIds }\n : {}),\n ...(body.promotionCodes !== undefined\n ? { promotionCodes: body.promotionCodes }\n : {}),\n ...(body.shippingAddress != null\n ? {\n shippingAddress: {\n line1: body.shippingAddress.line1,\n city: body.shippingAddress.city,\n postalCode: body.shippingAddress.postalCode,\n country: body.shippingAddress.country,\n ...(body.shippingAddress.line2 != null ? { line2: body.shippingAddress.line2 } : {}),\n ...(body.shippingAddress.state != null ? { state: body.shippingAddress.state } : {}),\n },\n }\n : {}),\n };\n\n // ── Phase 1: Validate & Calculate (inside DB transaction — fast SQL only) ──\n const validationHooks: BeforeHook<CheckoutData>[] = [\n validateCartNotEmpty,\n resolveCurrentPrices,\n checkInventoryAvailability,\n applyPromotionCodes,\n calculateTax,\n calculateShipping,\n ...(kernel.hooks.resolve(\"checkout.beforePayment\") as BeforeHook<CheckoutData>[]),\n validatePaymentMethod,\n ];\n\n // ── Phase 2: Payment Authorization (outside transaction — external API call) ──\n const paymentHooks: BeforeHook<CheckoutData>[] = [\n authorizePayment,\n ...(kernel.hooks.resolve(\"checkout.beforeCreate\") as BeforeHook<CheckoutData>[]),\n ];\n\n const afterHooks: AfterHook<OrderResult>[] = [\n completeCheckout,\n recordAnalyticsEvent,\n ...(kernel.hooks.resolve(\"checkout.afterCreate\") as AfterHook<OrderResult>[]),\n ];\n\n const context = createHookContext({\n actor,\n logger: kernel.logger,\n services: kernel.services as ServiceContainer,\n context: { moduleName: \"checkout\" },\n origin: \"rest\",\n kernel: kernel as unknown as { database: { db: import(\"../../../kernel/database/plugin-types\").PluginDb } },\n });\n\n try {\n // Phase 1: DB transaction for validation — releases connection immediately after\n const validated = await kernel.database.transaction(async (_tx) => {\n context.tx = _tx;\n return runBeforeHooks(\n validationHooks,\n checkoutData,\n \"create\",\n context,\n );\n });\n\n // Phase 2: Payment authorization — NO DB connection held while calling Stripe/etc.\n // If Stripe takes 5s, the DB connection pool is not affected.\n context.tx = null;\n const processed = await runBeforeHooks(\n paymentHooks,\n validated,\n \"create\",\n context,\n );\n\n // Resolve customer profile UUID from customerId (may be a profile UUID or a Better Auth user_id)\n let customerUuid: string | undefined = undefined;\n if (processed.customerId) {\n const uuidRe = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n if (uuidRe.test(processed.customerId)) {\n // Looks like a profile UUID — try direct lookup (no auto-create)\n const byIdResult = await kernel.services.customers.getById(\n processed.customerId,\n actor,\n );\n if (byIdResult.ok) {\n customerUuid = byIdResult.value.id;\n }\n }\n if (!customerUuid) {\n // Fall back to user_id lookup (auto-creates customer profile if needed)\n const byUserIdResult = await kernel.services.customers.getByUserId(\n processed.customerId,\n actor,\n );\n if (byUserIdResult.ok) {\n customerUuid = byUserIdResult.value.id;\n }\n }\n // If both lookups fail, we still allow guest checkout (customerUuid remains undefined)\n }\n\n const orderPayload = {\n currency: processed.currency,\n subtotal: processed.subtotal,\n taxTotal: processed.taxTotal,\n shippingTotal: processed.shippingTotal,\n discountTotal: processed.discountTotal,\n grandTotal: processed.total,\n paymentIntentId: processed.paymentIntentId,\n paymentMethodId: processed.paymentMethodId,\n metadata: {\n // H2 fix: Merge hook-injected metadata (e.g., BNPL fee) before core fields\n ...(typeof processed.metadata === \"object\" && processed.metadata !== null\n ? processed.metadata\n : {}),\n cartId: processed.cartId,\n paymentIntentId: processed.paymentIntentId,\n checkoutId: processed.checkoutId,\n promotionCodes: processed.promotionCodes,\n appliedPromotions: processed.appliedPromotions,\n shippingAddress: processed.shippingAddress,\n },\n lineItems: processed.lineItems.map((lineItem) => {\n const payload = {\n entityId: lineItem.entityId,\n entityType: lineItem.entityType ?? \"product\",\n title: lineItem.title ?? lineItem.entityId,\n quantity: lineItem.quantity,\n unitPrice: lineItem.resolvedUnitPrice ?? 0,\n totalPrice: lineItem.resolvedTotal ?? 0,\n };\n return lineItem.variantId !== undefined\n ? { ...payload, variantId: lineItem.variantId }\n : payload;\n }),\n ...(customerUuid !== undefined\n ? { customerId: customerUuid }\n : {}),\n };\n\n const order = await kernel.services.orders.create(orderPayload, actor);\n\n if (!order.ok) {\n return c.json(\n mapErrorToResponse(order.error),\n mapErrorToStatus(order.error),\n );\n }\n\n if (order.ok && (processed.appliedPromotions?.length ?? 0) > 0) {\n await kernel.services.promotions.recordUsage({\n promotions: processed.appliedPromotions ?? [],\n orderId: order.value.id,\n ...(customerUuid !== undefined\n ? { customerId: customerUuid }\n : {}),\n });\n }\n\n if (order.ok) {\n await kernel.services.tax.reportTransaction({\n transactionId: order.value.id,\n transactionDate: new Date(),\n currency: processed.currency,\n amount:\n processed.subtotal -\n processed.discountTotal +\n processed.shippingTotal,\n shipping: processed.shippingTotal,\n salesTax: processed.taxTotal,\n lineItems: processed.lineItems.map((lineItem, index) => ({\n id: lineItem.id ?? `${order.value.id}-${index + 1}`,\n entityId: lineItem.entityId,\n description: lineItem.title ?? lineItem.entityId,\n quantity: lineItem.quantity,\n unitPrice: lineItem.resolvedUnitPrice ?? 0,\n ...(lineItem.discountAmount !== undefined\n ? { discount: lineItem.discountAmount }\n : {}),\n })),\n ...(customerUuid !== undefined\n ? { customerId: customerUuid }\n : {}),\n ...(processed.shippingAddress !== undefined\n ? { toAddress: processed.shippingAddress }\n : {}),\n });\n }\n\n // Stash paymentMethodId for completeCheckout compensation chain\n context.context.paymentMethodId = processed.paymentMethodId;\n\n const afterReport = await runAfterHooks(\n afterHooks,\n null,\n order.value,\n \"create\",\n context,\n );\n\n await kernel.services.cart.markAsCheckedOut(body.cartId, actor);\n\n return c.json(\n {\n data: {\n ...order.value,\n // Stripe Elements requires clientSecret to collect card details on the frontend\n ...(processed.paymentClientSecret\n ? { paymentClientSecret: processed.paymentClientSecret }\n : {}),\n },\n meta: afterReport.hasErrors\n ? { hookErrors: afterReport.errors }\n : undefined,\n },\n 201,\n );\n } catch (error) {\n const message = isCommerceError(error)\n ? error.message\n : \"Checkout failed.\";\n return c.json(\n {\n error: {\n code: \"CHECKOUT_FAILED\",\n message,\n },\n },\n 422,\n );\n }\n });\n\n return router;\n}\n",
|
|
56
|
+
"import { z, createRoute } from \"@hono/zod-openapi\";\nimport { ErrorSchema, errorResponses } from \"./shared\";\n\n// ─── Request Schema ──────────────────────────────────────────────────────────\n\nexport const CheckoutBodySchema = z.object({\n cartId: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n paymentMethodId: z.string().openapi({ example: \"pm_card_visa\" }),\n customerId: z.string().optional().openapi({ example: \"customer-uuid-or-user-id\" }),\n customerGroupIds: z.array(z.string()).optional(),\n currency: z.string().length(3).optional().openapi({ example: \"USD\" }),\n promotionCodes: z.array(z.string()).optional().openapi({ example: [\"SUMMER10\"] }),\n shippingAddress: z.object({\n line1: z.string(),\n line2: z.string().optional(),\n city: z.string(),\n state: z.string().optional(),\n postalCode: z.string(),\n country: z.string(),\n }).optional(),\n}).openapi(\"CheckoutRequest\");\n\n// ─── Response Schema ─────────────────────────────────────────────────────────\n\nexport const OrderResponseSchema = z.object({\n data: z.object({\n id: z.uuid(),\n orderNumber: z.string(),\n status: z.string(),\n currency: z.string(),\n subtotal: z.number(),\n taxTotal: z.number(),\n shippingTotal: z.number(),\n discountTotal: z.number(),\n grandTotal: z.number(),\n placedAt: z.string(),\n }),\n meta: z.object({\n hookErrors: z.array(z.string()),\n }).optional(),\n}).openapi(\"CheckoutResponse\");\n\n// ─── Route Definition ────────────────────────────────────────────────────────\n\nexport const checkoutRoute = createRoute({\n method: \"post\",\n path: \"/\",\n tags: [\"Checkout\"],\n summary: \"Process checkout and create an order\",\n description: \"Validates cart, reserves inventory, authorizes payment, calculates tax/shipping, and creates the order.\",\n request: {\n body: {\n content: {\n \"application/json\": { schema: CheckoutBodySchema },\n },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { \"application/json\": { schema: OrderResponseSchema } },\n description: \"Order created successfully.\",\n },\n ...errorResponses,\n },\n});\n",
|
|
57
|
+
"import type { CompensationContext, Step } from \"./types\";\nimport type { Result } from \"../result\";\n\n/**\n * AnyStep erases the output type parameter so that heterogeneous step\n * arrays can be passed to runCompensationChain without variance issues\n * under exactOptionalPropertyTypes.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- erases output type for heterogeneous step arrays; unknown breaks contravariance on compensate()\ntype AnyStep<TInput> = Step<TInput, any>;\n\n/**\n * Runs a list of steps in order. If any step fails, compensates all\n * previously completed steps in reverse. Steps share the same input\n * object (they may mutate it to enrich downstream steps, following\n * the same pattern established by BeforeHooks).\n *\n * Compensation failures are logged but do not override the original error.\n * A failed compensation is a separate operational concern that requires\n * manual review — it should never mask the root cause returned to the caller.\n */\nexport async function runCompensationChain<TInput>(\n steps: ReadonlyArray<AnyStep<TInput>>,\n input: TInput,\n ctx: CompensationContext,\n): Promise<Result<TInput>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- matches AnyStep output erasure\n const completed: Array<{ step: AnyStep<TInput>; output: any }> = [];\n\n for (const step of steps) {\n const result = await step.run(input, ctx);\n\n if (!result.ok) {\n ctx.hook.logger.error(\n `Compensation chain failed at step \"${step.id}\". ` +\n `Running ${completed.length} compensation(s).`,\n { error: result.error },\n );\n\n // Compensate in reverse order — most recently completed step first\n for (const done of [...completed].reverse()) {\n if (!done.step.compensate) continue;\n try {\n await done.step.compensate(done.output, ctx);\n ctx.hook.logger.info(`Compensated step \"${done.step.id}\"`);\n } catch (compensateError) {\n ctx.hook.logger.error(\n `Compensation for step \"${done.step.id}\" failed. Manual review required.`,\n { compensateError },\n );\n }\n }\n\n return result;\n }\n\n completed.push({ step, output: result.value });\n }\n\n return { ok: true, value: input };\n}\n",
|
|
58
|
+
"import type { CommerceError } from \"./errors\";\n\nexport type Result<T, E = CommerceError> =\n | { ok: true; value: T; meta?: Record<string, unknown> }\n | { ok: false; error: E };\n\n/**\n * Simplified Result types for plugin services.\n * Plugin services return `PluginResult<T>` instead of `Result<T, CommerceError>`.\n * This matches the `{ ok: true; value: T } | { ok: false; error: string }` pattern\n * that every plugin has been copy-pasting.\n */\nexport type PluginResult<T> = { ok: true; value: T } | { ok: false; error: string; code?: string };\nexport type PluginResultErr = { ok: false; error: string; code?: string };\n\nexport function Ok<T>(value: T, meta?: Record<string, unknown>): Result<T, never> {\n if (meta !== undefined) {\n return { ok: true, value, meta };\n }\n return { ok: true, value };\n}\n\nexport function Err<E>(error: E): Result<never, E> {\n return { ok: false, error };\n}\n\n/**\n * String-based Err for plugin services.\n * Usage: `return PluginErr(\"Not found\", \"NOT_FOUND\")`\n */\nexport function PluginErr(error: string, code?: string): PluginResultErr {\n return code ? { ok: false, error, code } : { ok: false, error };\n}\n",
|
|
59
|
+
"import type { Step } from \"../kernel/compensation/types\";\nimport type { CheckoutData } from \"./checkout\";\nimport { Ok, Err } from \"../kernel/result\";\nimport { CommerceValidationError } from \"../kernel/errors\";\n\n// Service type narrowing — these mirror the actual service interfaces\n// without creating circular imports.\n\ninterface InventoryServiceLike {\n reserve(input: {\n entityId: string;\n variantId?: string;\n quantity: number;\n orderId: string;\n performedBy: string;\n }): Promise<{ ok: boolean; error?: { message: string } }>;\n release(input: {\n entityId: string;\n variantId?: string;\n quantity: number;\n orderId: string;\n performedBy: string;\n }): Promise<unknown>;\n}\n\ninterface PaymentsServiceLike {\n capture(\n paymentIntentId: string,\n amount?: number,\n ): Promise<{ ok: boolean; error?: { message: string } }>;\n refund(\n paymentId: string,\n amount: number,\n reason?: string,\n ): Promise<unknown>;\n}\n\ninterface OrdersServiceLike {\n updateStatus?(\n orderId: string,\n status: string,\n reason?: string,\n ): Promise<unknown>;\n}\n\n/**\n * Reservation record produced by the reserve-inventory step.\n * Passed to compensate() so it knows exactly what to undo.\n */\nexport interface InventoryReservation {\n entityId: string;\n variantId: string | undefined;\n quantity: number;\n orderId: string;\n}\n\n/**\n * Step 1: Reserve inventory.\n *\n * Output: the list of reservations created.\n * Compensate: release each reservation.\n *\n * Inventory reservation runs BEFORE payment capture. This is deliberate:\n * if stock is unavailable, we should find out before charging the customer.\n * The compensation for this step releases the reserved quantities.\n */\nexport const reserveInventoryStep: Step<\n CheckoutData,\n InventoryReservation[]\n> = {\n id: \"reserve-inventory\",\n\n async run(data, ctx) {\n const inventory = ctx.hook.services.inventory as InventoryServiceLike;\n const reservations: InventoryReservation[] = [];\n const performedBy = ctx.hook.actor?.userId ?? \"system\";\n\n for (const item of data.lineItems) {\n const result = await inventory.reserve({\n entityId: item.entityId,\n ...(item.variantId != null ? { variantId: item.variantId } : {}),\n quantity: item.quantity,\n orderId: data.checkoutId,\n performedBy,\n });\n\n if (!result.ok) {\n return Err(\n new CommerceValidationError(\n `Inventory reservation failed for ${item.title ?? item.entityId}: ${result.error?.message ?? \"unknown\"}`,\n ),\n );\n }\n\n reservations.push({\n entityId: item.entityId,\n variantId: item.variantId,\n quantity: item.quantity,\n orderId: data.checkoutId,\n });\n }\n\n return Ok(reservations);\n },\n\n async compensate(reservations, ctx) {\n const inventory = ctx.hook.services.inventory as InventoryServiceLike;\n const performedBy = ctx.hook.actor?.userId ?? \"system\";\n\n for (const r of reservations) {\n await inventory.release({\n entityId: r.entityId,\n ...(r.variantId != null ? { variantId: r.variantId } : {}),\n quantity: r.quantity,\n orderId: r.orderId,\n performedBy,\n });\n }\n },\n};\n\n/**\n * Step 2: Capture payment.\n *\n * Output: the captured payment intent ID and amount.\n * Compensate: issue a full refund via the payments service.\n *\n * Runs AFTER inventory reservation. If capture fails, inventory reservations\n * are released by the compensation chain. If capture succeeds but a later step\n * fails, a refund is issued.\n */\nexport const capturePaymentStep: Step<\n CheckoutData,\n { paymentIntentId: string; amount: number }\n> = {\n id: \"capture-payment\",\n\n async run(data, ctx) {\n if (!data.paymentIntentId) {\n return Err(\n new CommerceValidationError(\n \"No authorized payment intent to capture.\",\n ),\n );\n }\n\n const payments = ctx.hook.services.payments as PaymentsServiceLike;\n const result = await payments.capture(data.paymentIntentId);\n\n if (!result.ok) {\n return Err(\n new CommerceValidationError(\n `Payment capture failed: ${result.error?.message ?? \"unknown\"}`,\n ),\n );\n }\n\n return Ok({ paymentIntentId: data.paymentIntentId, amount: data.total });\n },\n\n async compensate({ paymentIntentId, amount }, ctx) {\n const payments = ctx.hook.services.payments as PaymentsServiceLike;\n await payments.refund(\n paymentIntentId,\n amount,\n \"Checkout compensation: downstream step failed after payment capture\",\n );\n },\n};\n\n/**\n * Step 3: Initiate fulfillment.\n *\n * Output: the order ID (for logging).\n * No compensate: fulfillment initiation is best-effort and idempotent.\n * A failed fulfillment should be retried through the job queue, not\n * compensated by rolling back the entire checkout.\n */\nexport const initiateFulfillmentStep: Step<\n CheckoutData,\n { orderId: string }\n> = {\n id: \"initiate-fulfillment\",\n\n async run(data, ctx) {\n const fulfillment = ctx.hook.services.fulfillment as {\n fulfillOrder(orderId: string, actor?: unknown): Promise<unknown>;\n };\n\n try {\n await fulfillment.fulfillOrder(data.checkoutId, ctx.hook.actor);\n } catch (error) {\n // Fulfillment initiation failure should not fail the checkout.\n // The order is paid and inventory is reserved — fulfillment can be retried.\n ctx.hook.logger.warn(\n `Fulfillment initiation failed for order ${data.checkoutId}. Will need manual retry.`,\n { error },\n );\n }\n\n return Ok({ orderId: data.checkoutId });\n },\n\n // No compensate — fulfillment is best-effort at this stage\n};\n\n/**\n * Step 4: Send confirmation email.\n *\n * Output: void (best-effort).\n * No compensate: you cannot unsend an email.\n */\nexport const sendConfirmationStep: Step<\n CheckoutData,\n { sent: boolean }\n> = {\n id: \"send-confirmation\",\n\n async run(data, ctx) {\n const customers = ctx.hook.services.customers as {\n getByUserId(\n userId: string,\n actor?: unknown,\n ): Promise<{ ok: boolean; value?: { email?: string } }>;\n };\n const email = ctx.hook.services.email as\n | {\n send(input: {\n template: string;\n to: string;\n data?: Record<string, unknown>;\n }): Promise<void>;\n }\n | undefined;\n\n if (!data.customerId || !email?.send) {\n return Ok({ sent: false });\n }\n\n try {\n const customer = await customers.getByUserId(data.customerId, ctx.hook.actor);\n if (customer.ok && customer.value?.email) {\n await email.send({\n template: \"order-confirmation\",\n to: customer.value.email,\n data: { orderId: data.checkoutId, total: data.total, currency: data.currency },\n });\n return Ok({ sent: true });\n }\n } catch (error) {\n // Email failure should not fail checkout\n ctx.hook.logger.warn(\n `Confirmation email failed for order ${data.checkoutId}.`,\n { error },\n );\n }\n\n return Ok({ sent: false });\n },\n\n // No compensate — cannot unsend an email\n};\n",
|
|
60
|
+
"import { CommerceValidationError } from \"../kernel/errors\";\nimport type { AfterHook, BeforeHook } from \"../kernel/hooks/types\";\nimport type { ShippingAddress } from \"../modules/shipping/calculator\";\nimport type { AppliedPromotion } from \"../modules/promotions/service\";\nimport { runCompensationChain } from \"../kernel/compensation/executor\";\nimport type { CompensationContext } from \"../kernel/compensation/types\";\nimport type { TxContext } from \"../kernel/database/tx-context\";\nimport {\n reserveInventoryStep,\n capturePaymentStep,\n initiateFulfillmentStep,\n sendConfirmationStep,\n} from \"./checkout-completion\";\n\nexport interface OrderResult {\n id: string;\n status?: string | undefined;\n customerId?: string | null | undefined;\n currency: string;\n subtotal?: number | undefined;\n discountTotal?: number | undefined;\n taxTotal?: number | undefined;\n shippingTotal?: number | undefined;\n grandTotal?: number | undefined;\n metadata?: Record<string, unknown> | null | undefined;\n lineItems?: Array<{\n entityId: string;\n entityType?: string | undefined;\n title?: string | undefined;\n variantId?: string | null | undefined;\n quantity: number;\n unitPrice?: number | undefined;\n totalPrice?: number | undefined;\n }> | undefined;\n}\n\nexport interface CheckoutLineItem {\n id?: string;\n entityId: string;\n entityType?: string;\n title?: string;\n variantId?: string;\n quantity: number;\n resolvedUnitPrice?: number;\n resolvedTotal?: number;\n discountAmount?: number;\n taxAmount?: number;\n priceBreakdown?: Array<{\n label: string;\n amountBefore: number;\n delta: number;\n amountAfter: number;\n }>;\n}\n\nexport interface CheckoutData {\n checkoutId: string;\n cartId: string;\n customerId?: string;\n customerGroupIds?: string[];\n currency: string;\n paymentMethodId: string;\n lineItems: CheckoutLineItem[];\n subtotal: number;\n discountTotal: number;\n taxTotal: number;\n shippingTotal: number;\n total: number;\n promotionCodes?: string[];\n paymentIntentId?: string;\n paymentClientSecret?: string | undefined;\n shippingAddress?: ShippingAddress;\n appliedPromotions?: AppliedPromotion[];\n freeShipping?: boolean;\n taxTransactionId?: string;\n metadata?: Record<string, unknown>;\n}\n\nfunction recalculateTotals(data: CheckoutData): void {\n data.total = Math.max(\n 0,\n data.subtotal - data.discountTotal + data.taxTotal + data.shippingTotal,\n );\n}\n\nexport const validateCartNotEmpty: BeforeHook<CheckoutData> = async ({\n data,\n context,\n}) => {\n const cartService = context.services.cart as {\n getById(id: string, actor?: unknown): Promise<\n | {\n ok: true;\n value: {\n organizationId?: string;\n status?: string;\n expiresAt?: Date | string;\n lineItems: Array<{\n id: string;\n entityId: string;\n variantId?: string | null;\n quantity: number;\n }>;\n };\n }\n | { ok: false }\n >;\n claimForCheckout(cartId: string, ctx?: unknown): Promise<\n | { ok: true; value: { id: string } }\n | { ok: false; error: { message: string } }\n >;\n };\n const catalogService = context.services.catalog as {\n getById(\n id: string,\n options?: { includeAttributes?: boolean },\n ): Promise<\n | {\n ok: true;\n value: {\n type: string;\n attributes?: Array<{ title: string; locale: string }>;\n };\n }\n | { ok: false }\n >;\n };\n\n // M1 fix: Atomically claim the cart for checkout (active → checking_out).\n // If a concurrent request already claimed it, this returns Err and we fail fast.\n const claimed = await cartService.claimForCheckout(data.cartId, context.tx);\n if (!claimed.ok) {\n throw new CommerceValidationError(\n \"Cart is not available for checkout. It may have already been checked out by a concurrent request.\",\n );\n }\n\n const cart = await cartService.getById(data.cartId, context.actor);\n if (!cart.ok || cart.value.lineItems.length === 0) {\n throw new CommerceValidationError(\"Cannot checkout an empty cart.\");\n }\n\n // Cross-org guard: prevent org B from checking out org A's cart\n const actorOrgId = context.actor?.organizationId ?? \"org_default\";\n if (cart.value.organizationId && cart.value.organizationId !== actorOrgId) {\n throw new CommerceValidationError(\"Cart does not belong to this organization.\");\n }\n\n // Reject expired carts\n if (cart.value.expiresAt) {\n const expiry = cart.value.expiresAt instanceof Date ? cart.value.expiresAt : new Date(cart.value.expiresAt);\n if (expiry.getTime() < Date.now()) {\n throw new CommerceValidationError(\"Cart has expired. Please create a new cart.\");\n }\n }\n\n // Enrich line items with entity title and type from catalog (in parallel)\n data.lineItems = await Promise.all(\n cart.value.lineItems.map(async (item) => {\n const entity = await catalogService.getById(item.entityId, {\n includeAttributes: true,\n });\n const title = entity.ok\n ? (entity.value.attributes?.[0]?.title ?? item.entityId)\n : item.entityId;\n const entityType = entity.ok ? entity.value.type : \"product\";\n return {\n id: item.id,\n entityId: item.entityId,\n entityType,\n title,\n quantity: item.quantity,\n // Use != null to exclude both null (DB value) and undefined\n ...(item.variantId != null ? { variantId: item.variantId } : {}),\n };\n }),\n );\n\n return data;\n};\n\nexport const resolveCurrentPrices: BeforeHook<CheckoutData> = async ({\n data,\n context,\n}) => {\n const pricing = context.services.pricing as {\n resolve(params: {\n entityId: string;\n variantId?: string;\n currency: string;\n quantity: number;\n customerId?: string;\n customerGroupIds?: string[];\n }): Promise<\n | {\n ok: true;\n value: {\n finalAmount: number;\n breakdown: Array<{\n label: string;\n amountBefore: number;\n delta: number;\n amountAfter: number;\n }>;\n };\n }\n | { ok: false }\n >;\n };\n\n for (const item of data.lineItems) {\n const price = await pricing.resolve({\n entityId: item.entityId,\n currency: data.currency,\n quantity: item.quantity,\n ...(item.variantId !== undefined ? { variantId: item.variantId } : {}),\n ...(data.customerId !== undefined ? { customerId: data.customerId } : {}),\n ...(data.customerGroupIds !== undefined\n ? { customerGroupIds: data.customerGroupIds }\n : {}),\n });\n\n if (!price.ok) {\n throw new CommerceValidationError(\n `Cannot resolve price for ${item.entityId}.`,\n );\n }\n\n item.resolvedUnitPrice = price.value.finalAmount;\n item.resolvedTotal = price.value.finalAmount * item.quantity;\n item.priceBreakdown = price.value.breakdown;\n item.discountAmount = 0;\n item.taxAmount = 0;\n }\n\n data.subtotal = data.lineItems.reduce(\n (sum, item) => sum + (item.resolvedTotal ?? 0),\n 0,\n );\n recalculateTotals(data);\n return data;\n};\n\nexport const checkInventoryAvailability: BeforeHook<CheckoutData> = async ({\n data,\n context,\n}) => {\n const inventory = context.services.inventory as {\n getAvailable(\n entityId: string,\n variantId?: string,\n ctx?: unknown,\n ): Promise<{ ok: boolean; value?: number }>;\n };\n\n for (const item of data.lineItems) {\n const available = await inventory.getAvailable(\n item.entityId,\n item.variantId,\n context.tx,\n );\n if (!available.ok || (available.value ?? 0) < item.quantity) {\n throw new CommerceValidationError(\n `Insufficient stock for ${item.title ?? item.entityId}. Available: ${\n available.ok ? (available.value ?? 0) : 0\n }, requested: ${item.quantity}.`,\n );\n }\n }\n\n return data;\n};\n\nexport const applyPromotionCodes: BeforeHook<CheckoutData> = async ({\n data,\n context,\n}) => {\n const promotions = context.services.promotions as {\n applyPromotions(input: {\n orgId?: string;\n cartId?: string;\n customerId?: string;\n customerGroupIds?: string[];\n currency: string;\n subtotal: number;\n lineItems: Array<{\n entityId: string;\n entityType: string;\n quantity: number;\n unitPrice: number;\n totalPrice: number;\n }>;\n promotionCodes?: string[];\n }): Promise<\n | {\n ok: true;\n value: {\n totalDiscount: number;\n freeShipping: boolean;\n applied: AppliedPromotion[];\n rejectedCodes: Array<{ code: string; reason: string }>;\n };\n }\n | { ok: false; error: Error }\n >;\n };\n\n const result = await promotions.applyPromotions({\n orgId: context.actor?.organizationId ?? \"org_default\",\n cartId: data.cartId,\n currency: data.currency,\n subtotal: data.subtotal,\n lineItems: data.lineItems.map((lineItem) => ({\n entityId: lineItem.entityId,\n entityType: lineItem.entityType ?? \"product\",\n quantity: lineItem.quantity,\n unitPrice: lineItem.resolvedUnitPrice ?? 0,\n totalPrice: lineItem.resolvedTotal ?? 0,\n })),\n ...(data.customerId !== undefined ? { customerId: data.customerId } : {}),\n ...(data.customerGroupIds !== undefined\n ? { customerGroupIds: data.customerGroupIds }\n : {}),\n ...(data.promotionCodes !== undefined\n ? { promotionCodes: data.promotionCodes }\n : {}),\n });\n\n if (!result.ok) {\n throw new CommerceValidationError(\n `Promotion application failed: ${result.error.message}`,\n );\n }\n\n data.discountTotal = result.value.totalDiscount;\n data.appliedPromotions = result.value.applied;\n data.freeShipping = result.value.freeShipping;\n\n recalculateTotals(data);\n return data;\n};\n\nexport const calculateTax: BeforeHook<CheckoutData> = async ({\n data,\n context,\n}) => {\n const tax = context.services.tax as {\n calculate(input: {\n currency: string;\n customerId?: string;\n shippingAmount: number;\n fromAddress?: ShippingAddress;\n toAddress?: ShippingAddress;\n lineItems: Array<{\n id: string;\n entityId: string;\n description: string;\n quantity: number;\n unitPrice: number;\n discount?: number;\n }>;\n }): Promise<\n | { ok: true; value: { amountToCollect: number } }\n | { ok: false; error: Error }\n >;\n };\n\n const calculated = await tax.calculate({\n currency: data.currency,\n shippingAmount: data.shippingTotal,\n lineItems: data.lineItems.map((lineItem) => ({\n id: lineItem.id ?? `${lineItem.entityId}:${lineItem.variantId ?? \"_\"}`,\n entityId: lineItem.entityId,\n description: lineItem.title ?? lineItem.entityId,\n quantity: lineItem.quantity,\n unitPrice: lineItem.resolvedUnitPrice ?? 0,\n ...(lineItem.discountAmount !== undefined\n ? { discount: lineItem.discountAmount }\n : {}),\n })),\n ...(data.customerId !== undefined ? { customerId: data.customerId } : {}),\n ...(data.shippingAddress !== undefined\n ? { toAddress: data.shippingAddress }\n : {}),\n });\n\n if (!calculated.ok) {\n throw new CommerceValidationError(\n `Tax calculation failed: ${calculated.error.message}`,\n );\n }\n\n data.taxTotal = Math.max(0, Math.round(calculated.value.amountToCollect));\n recalculateTotals(data);\n return data;\n};\n\nexport const calculateShipping: BeforeHook<CheckoutData> = async ({\n data,\n context,\n}) => {\n const shippingService = context.services.shipping as {\n calculate(input: {\n lineItems: Array<{\n entityId: string;\n variantId?: string;\n quantity: number;\n resolvedTotal: number;\n }>;\n subtotalAfterDiscount: number;\n currency: string;\n address?: ShippingAddress;\n isFreeShipping?: boolean;\n }): Promise<\n | {\n ok: true;\n value: { amount: number; strategy: string; weightGrams: number };\n }\n | { ok: false; error: Error }\n >;\n };\n\n const shipping = await shippingService.calculate({\n lineItems: data.lineItems.map((lineItem) => ({\n entityId: lineItem.entityId,\n quantity: lineItem.quantity,\n resolvedTotal: lineItem.resolvedTotal ?? 0,\n ...(lineItem.variantId !== undefined\n ? { variantId: lineItem.variantId }\n : {}),\n })),\n subtotalAfterDiscount: Math.max(0, data.subtotal - data.discountTotal),\n currency: data.currency,\n ...(data.shippingAddress !== undefined\n ? { address: data.shippingAddress }\n : {}),\n ...(data.freeShipping !== undefined\n ? { isFreeShipping: data.freeShipping }\n : {}),\n });\n\n if (!shipping.ok) {\n throw new CommerceValidationError(\n `Shipping calculation failed: ${shipping.error.message}`,\n );\n }\n\n data.shippingTotal = shipping.value.amount;\n recalculateTotals(data);\n return data;\n};\n\nexport const validatePaymentMethod: BeforeHook<CheckoutData> = async ({\n data,\n context,\n}) => {\n if (!data.paymentMethodId) {\n throw new CommerceValidationError(\"Payment method is required.\");\n }\n\n // H1 fix: Validate paymentMethodId against registered adapters\n const payments = context.services.payments as {\n registeredProviderIds?: string[];\n };\n if (\n payments.registeredProviderIds &&\n payments.registeredProviderIds.length > 0 &&\n !payments.registeredProviderIds.includes(data.paymentMethodId)\n ) {\n throw new CommerceValidationError(\n `Unknown payment method \"${data.paymentMethodId}\". ` +\n `Available methods: [${payments.registeredProviderIds.join(\", \")}].`,\n );\n }\n\n return data;\n};\n\nexport const authorizePayment: BeforeHook<CheckoutData> = async ({\n data,\n context,\n}) => {\n const payments = context.services.payments as {\n authorize(input: {\n amount: number;\n currency: string;\n paymentMethodId: string;\n customerId?: string;\n metadata: Record<string, unknown>;\n }): Promise<{\n ok: boolean;\n value?: { id: string; clientSecret?: string | null };\n error?: { message: string };\n }>;\n };\n const authorized = await payments.authorize({\n amount: data.total,\n currency: data.currency,\n paymentMethodId: data.paymentMethodId,\n metadata: {\n checkoutId: data.checkoutId,\n cartId: data.cartId,\n },\n ...(data.customerId !== undefined ? { customerId: data.customerId } : {}),\n });\n\n if (!authorized.ok || !authorized.value) {\n throw new CommerceValidationError(\n `Payment authorization failed: ${authorized.error?.message ?? \"Unknown payment error.\"}`,\n );\n }\n\n data.paymentIntentId = authorized.value.id;\n data.paymentClientSecret = authorized.value.clientSecret ?? undefined;\n context.context.paymentIntentId = authorized.value.id;\n return data;\n};\n\nexport const capturePayment: AfterHook<OrderResult> = async ({ context }) => {\n const payments = context.services.payments as {\n capture(paymentIntentId: string, amount?: number, paymentMethodId?: string): Promise<unknown>;\n };\n const paymentIntentId = context.context.paymentIntentId as string | undefined;\n const paymentMethodId = context.context.paymentMethodId as string | undefined;\n if (!paymentIntentId) return;\n await payments.capture(paymentIntentId, undefined, paymentMethodId);\n};\n\nexport const reserveInventory: AfterHook<OrderResult> = async ({ result, context }) => {\n const inventory = context.services.inventory as {\n reserve(input: {\n entityId: string;\n variantId?: string;\n quantity: number;\n orderId: string;\n performedBy: string;\n }): Promise<unknown>;\n };\n for (const lineItem of result.lineItems ?? []) {\n await inventory.reserve({\n entityId: lineItem.entityId,\n ...(lineItem.variantId != null ? { variantId: lineItem.variantId } : {}),\n quantity: lineItem.quantity,\n orderId: result.id,\n performedBy: context.actor?.userId ?? \"system\",\n });\n }\n};\n\nexport const initiateFulfillment: AfterHook<OrderResult> = async ({\n result,\n context,\n}) => {\n const fulfillment = context.services.fulfillment as {\n fulfillOrder(orderId: string, actor?: unknown): Promise<unknown>;\n };\n await fulfillment.fulfillOrder(result.id, context.actor);\n};\n\nexport const sendConfirmation: AfterHook<OrderResult> = async ({ result, context }) => {\n const customers = context.services.customers as {\n getByUserId(\n userId: string,\n actor?: unknown,\n ): Promise<{ ok: boolean; value?: { email?: string } }>;\n };\n const email = context.services.email as\n | {\n send(input: {\n template: string;\n to: string;\n data?: Record<string, unknown>;\n }): Promise<void>;\n }\n | undefined;\n\n if (!result.customerId || !email?.send) return;\n const customer = await customers.getByUserId(result.customerId, context.actor);\n if (!customer.ok || !customer.value?.email) return;\n\n await email.send({\n template: \"order-confirmation\",\n to: customer.value.email,\n data: { order: result },\n });\n};\n\n/**\n * Analytics event recording — no-op since RFC-006.\n *\n * The DrizzleAnalyticsAdapter queries source tables (orders, inventory)\n * directly via SQL. No separate event recording is needed.\n * Kept as an export for backwards compatibility with checkout route.\n */\nexport const recordAnalyticsEvent: AfterHook<OrderResult> = async () => {\n // No-op: source tables ARE the analytics events (RFC-006)\n};\n\n/**\n * Replaces the separate capturePayment and reserveInventory AfterHooks\n * with a single compensation chain that can roll back completed steps\n * if any step fails.\n *\n * Order of steps:\n * 1. Reserve inventory — if this fails, no money is charged\n * 2. Capture payment — if this fails, inventory reservations are released\n * 3. Initiate fulfillment — best-effort, does not fail the chain\n * 4. Send confirmation — best-effort, does not fail the chain\n *\n * Both failure modes leave the system in a consistent state.\n */\nexport const completeCheckout: AfterHook<OrderResult> = async ({\n result: order,\n context,\n}) => {\n const paymentIntentId = context.context.paymentIntentId as\n | string\n | undefined;\n\n const checkoutData: CheckoutData = {\n checkoutId: order.id,\n cartId: (order.metadata?.cartId as string) ?? \"\",\n ...(order.customerId != null ? { customerId: order.customerId } : {}),\n currency: order.currency,\n paymentMethodId: (context.context.paymentMethodId as string) ?? \"\",\n lineItems: (order.lineItems ?? []).map((li) => ({\n id: li.entityId,\n entityId: li.entityId,\n ...(li.entityType != null ? { entityType: li.entityType } : {}),\n title: li.title ?? li.entityId,\n ...(li.variantId != null ? { variantId: li.variantId } : {}),\n quantity: li.quantity,\n ...(li.unitPrice != null ? { resolvedUnitPrice: li.unitPrice } : {}),\n ...(li.totalPrice != null ? { resolvedTotal: li.totalPrice } : {}),\n })),\n subtotal: order.subtotal ?? 0,\n discountTotal: order.discountTotal ?? 0,\n taxTotal: order.taxTotal ?? 0,\n shippingTotal: order.shippingTotal ?? 0,\n total: order.grandTotal ?? 0,\n ...(paymentIntentId != null ? { paymentIntentId } : {}),\n };\n\n const compensationCtx: CompensationContext = {\n tx: (context.tx as TxContext | null) ?? null,\n hook: context,\n };\n\n const chainResult = await runCompensationChain(\n [\n reserveInventoryStep,\n capturePaymentStep,\n initiateFulfillmentStep,\n sendConfirmationStep,\n ],\n checkoutData,\n compensationCtx,\n );\n\n if (!chainResult.ok) {\n // Mark order as failed if compensation chain did not succeed\n const orders = context.services.orders as {\n changeStatus?(input: { orderId: string; newStatus: string }, actor: unknown): Promise<unknown>;\n };\n if (orders.changeStatus) {\n try {\n await orders.changeStatus({ orderId: order.id, newStatus: \"cancelled\" }, context.actor);\n } catch (statusError) {\n context.logger.error(\n `Failed to update order ${order.id} status to cancelled after checkout failure.`,\n { statusError },\n );\n }\n }\n throw chainResult.error;\n }\n};\n",
|
|
61
|
+
"import type { AfterHook, BeforeHook, HookContext, HookOperation } from \"./types\";\n\nexport interface HookError {\n hookName: string;\n message: string;\n}\n\nexport interface HookReport {\n errors: HookError[];\n hasErrors: boolean;\n}\n\n/** Default hook timeout: 20 seconds */\nconst HOOK_TIMEOUT_MS = 20_000;\n\nfunction withTimeout<T>(promiseOrValue: Promise<T> | T, timeoutMs: number, hookName: string): Promise<T> {\n const promise = Promise.resolve(promiseOrValue);\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(\n () => reject(new Error(`Hook \"${hookName}\" timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n promise.then(\n (val) => { clearTimeout(timer); resolve(val); },\n (err) => { clearTimeout(timer); reject(err); },\n );\n });\n}\n\nexport async function runBeforeHooks<T>(\n hooks: BeforeHook<T>[],\n data: T,\n operation: HookOperation,\n context: HookContext,\n): Promise<T> {\n let current = data;\n for (const hook of hooks) {\n const hookName = hook.name || \"(anonymous beforeHook)\";\n try {\n current = await withTimeout(\n hook({ data: current, operation, context }),\n HOOK_TIMEOUT_MS,\n hookName,\n );\n } catch (error) {\n context.logger.error(`Before-hook \"${hookName}\" failed during ${operation}`, {\n error: error instanceof Error ? error.message : String(error),\n requestId: context.requestId,\n });\n throw error; // Re-throw — beforeHooks MUST succeed\n }\n }\n return current;\n}\n\nexport async function runAfterHooks<T>(\n hooks: AfterHook<T>[],\n originalData: T | null,\n committedResult: T,\n operation: HookOperation,\n context: HookContext,\n): Promise<HookReport> {\n const errors: HookError[] = [];\n for (const hook of hooks) {\n const hookName = hook.name || \"(anonymous afterHook)\";\n try {\n await withTimeout(\n hook({\n data: originalData,\n result: committedResult,\n operation,\n context,\n }),\n HOOK_TIMEOUT_MS,\n hookName,\n );\n } catch (error) {\n errors.push({\n hookName,\n message: error instanceof Error ? error.message : String(error),\n });\n context.logger.error(`After-hook \"${hookName}\" failed`, {\n error,\n });\n }\n }\n return { errors, hasErrors: errors.length > 0 };\n}\n",
|
|
62
|
+
"import { randomUUID } from \"node:crypto\";\nimport type { Actor } from \"../../auth/types\";\nimport type { JobsAdapter } from \"../jobs/adapter\";\nimport { NullJobsAdapter } from \"../jobs/adapter\";\nimport type { PluginDb } from \"../database/plugin-types\";\nimport type { HookContext, HookOrigin, Logger, ServiceContainer } from \"./types\";\n\nexport interface CreateHookContextArgs {\n actor: Actor | null;\n tx?: unknown;\n logger: Logger;\n services: ServiceContainer;\n context?: Record<string, unknown>;\n requestId?: string;\n origin?: HookOrigin;\n jobs?: JobsAdapter;\n db?: PluginDb;\n kernel?: { database: { db: PluginDb } };\n}\n\nconst nullJobs = new NullJobsAdapter();\n\n/**\n * Creates a HookContext with sensible defaults.\n */\nexport function createHookContext(args: CreateHookContextArgs): HookContext {\n // Resolve db: prefer explicit db arg, fall back to kernel.database.db\n const db = args.db ?? args.kernel?.database?.db ?? null;\n\n const ctx: HookContext = {\n actor: args.actor,\n tx: args.tx ?? null,\n logger: args.logger,\n services: args.services,\n context: args.context ?? {},\n requestId: args.requestId ?? randomUUID(),\n origin: args.origin ?? \"rest\",\n jobs: args.jobs ?? nullJobs,\n db: db as PluginDb,\n };\n\n return ctx;\n}\n",
|
|
63
|
+
"/**\n * Minimal interface for enqueueing background jobs.\n * The full DrizzleJobsAdapter implements this; hooks receive\n * it on HookContext.jobs so they can defer work without caring\n * about the underlying storage.\n */\nexport interface JobsAdapter {\n enqueue(\n taskSlug: string,\n input: Record<string, unknown>,\n options?: EnqueueOptions,\n ): Promise<string>;\n}\n\nexport interface EnqueueOptions {\n queue?: string;\n maxAttempts?: number;\n delayMs?: number;\n concurrencyKey?: string;\n supersedes?: boolean;\n organizationId?: string;\n}\n\n/**\n * No-op adapter used when no jobs backend is configured.\n * All enqueue calls silently succeed and return a placeholder ID.\n */\nexport class NullJobsAdapter implements JobsAdapter {\n async enqueue(\n _taskSlug: string,\n _input: Record<string, unknown>,\n _options?: EnqueueOptions,\n ): Promise<string> {\n return \"null-job-id\";\n }\n}\n",
|
|
64
|
+
"export function makeId(): string {\n return crypto.randomUUID();\n}\n",
|
|
65
|
+
"import { OpenAPIHono } from \"@hono/zod-openapi\";\nimport type { Kernel } from \"../../../runtime/kernel\";\nimport { changeOrderStatusRoute, listOrdersRoute, getOrderRoute, getOrderFulfillmentsRoute } from \"../schemas/orders\";\nimport { type AppEnv, isUUID, mapErrorToResponse, mapErrorToStatus, parsePagination } from \"../utils\";\n\nexport function orderRoutes(kernel: Kernel) {\n const router = new OpenAPIHono<AppEnv>();\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(listOrdersRoute, async (c) => {\n const pagination = parsePagination(c.req.query());\n const status = c.req.query(\"status\");\n const result = await kernel.services.orders.list(\n {\n page: pagination.page,\n limit: pagination.limit,\n ...(status !== undefined ? { status } : {}),\n },\n c.get(\"actor\"),\n );\n\n if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n return c.json({\n data: result.value.items,\n meta: {\n pagination: result.value.pagination,\n },\n });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(getOrderRoute, async (c) => {\n const idOrNumber = c.req.param(\"idOrNumber\");\n const result = isUUID(idOrNumber)\n ? await kernel.services.orders.getById(idOrNumber, c.get(\"actor\"))\n : await kernel.services.orders.getByNumber(idOrNumber, c.get(\"actor\"));\n\n if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi() enforces strict response typing but our handler\n // returns union responses (200 | 400 | 404). The route definition documents the\n // contract; the handler returns dynamic status.\n router.openapi(changeOrderStatusRoute, async (c) => {\n const body = c.req.valid(\"json\");\n const result = await kernel.services.orders.changeStatus(\n {\n orderId: c.req.param(\"id\"),\n newStatus: body.status,\n ...(body.reason !== undefined ? { reason: body.reason } : {}),\n },\n c.get(\"actor\"),\n );\n\n if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(getOrderFulfillmentsRoute, async (c) => {\n const orderId = c.req.param(\"id\");\n const actor = c.get(\"actor\");\n\n // Verify the order exists and the actor has access before returning fulfillments\n const orderResult = isUUID(orderId)\n ? await kernel.services.orders.getById(orderId, actor)\n : await kernel.services.orders.getByNumber(orderId, actor);\n\n if (!orderResult.ok) return c.json(mapErrorToResponse(orderResult.error), mapErrorToStatus(orderResult.error));\n\n const result = await kernel.services.fulfillment.getByOrderId(orderResult.value.id);\n if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n return c.json({ data: result.value });\n });\n\n return router;\n}\n",
|
|
66
|
+
"import { z, createRoute } from \"@hono/zod-openapi\";\nimport { ErrorSchema, errorResponses } from \"./shared\";\nimport { OrderResponse, OrderListResponse } from \"./responses\";\n\n// ─── Request Schemas ────────────────────────────────────────────────────────\n\nexport const ChangeOrderStatusBodySchema = z.object({\n // Accept any string — custom state machines (e.g., BNPL) add states like\n // \"payment_initiated\", \"shipped\", \"delivered\" etc. The order service's\n // state machine validates valid transitions at runtime.\n status: z.string().min(1).openapi({ example: \"confirmed\" }),\n reason: z.string().optional().openapi({ example: \"Payment verified\" }),\n}).openapi(\"ChangeOrderStatusRequest\");\n\n// ─── Response Schemas ───────────────────────────────────────────────────────\n\nexport const OrderDataResponseSchema = OrderResponse;\n\n// ─── Path Params ────────────────────────────────────────────────────────────\n\nconst OrderIdParam = z.object({\n id: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n});\n\n// ─── Route Definitions ──────────────────────────────────────────────────────\n\nexport const listOrdersRoute = createRoute({\n method: \"get\",\n path: \"/\",\n tags: [\"Orders\"],\n summary: \"List orders\",\n request: {\n query: z.object({\n status: z.string().optional(),\n page: z.string().optional(),\n limit: z.string().optional(),\n }),\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: OrderListResponse } },\n description: \"Success\",\n },\n },\n});\n\nexport const getOrderRoute = createRoute({\n method: \"get\",\n path: \"/{idOrNumber}\",\n tags: [\"Orders\"],\n summary: \"Get an order by ID or order number\",\n request: {\n params: z.object({\n idOrNumber: z.string().min(1).openapi({ example: \"ORD-001\" }),\n }),\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: OrderDataResponseSchema } },\n description: \"Success\",\n },\n ...errorResponses,\n },\n});\n\nexport const getOrderFulfillmentsRoute = createRoute({\n method: \"get\",\n path: \"/{id}/fulfillments\",\n tags: [\"Orders\"],\n summary: \"Get fulfillments for an order\",\n request: {\n params: OrderIdParam,\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: OrderDataResponseSchema } },\n description: \"Success\",\n },\n ...errorResponses,\n },\n});\n\nexport const changeOrderStatusRoute = createRoute({\n method: \"patch\",\n path: \"/{id}/status\",\n tags: [\"Orders\"],\n summary: \"Change the status of an order\",\n request: {\n params: OrderIdParam,\n body: {\n content: {\n \"application/json\": { schema: ChangeOrderStatusBodySchema },\n },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: OrderDataResponseSchema } },\n description: \"Order status updated.\",\n },\n ...errorResponses,\n },\n});\n",
|
|
67
|
+
"import { OpenAPIHono } from \"@hono/zod-openapi\";\nimport type { PgDatabase, PgQueryResultHKT } from \"drizzle-orm/pg-core\";\nimport type { Kernel } from \"../../../runtime/kernel\";\nimport { type AppEnv, mapErrorToResponse, mapErrorToStatus } from \"../utils\";\nimport { processedWebhookEvents } from \"../../../modules/webhooks/schema\";\n\ntype Db = PgDatabase<PgQueryResultHKT, Record<string, unknown>>;\n\nexport function paymentRoutes(kernel: Kernel) {\n const router = new OpenAPIHono<AppEnv>();\n\n router.post(\"/webhook\", async (c) => {\n const result = await kernel.services.payments.verifyWebhook(c.req.raw);\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n\n const event = result.value;\n const db = kernel.database.db as Db;\n\n // Atomic idempotency: INSERT ... ON CONFLICT DO NOTHING ... RETURNING\n // If the row already exists, RETURNING yields zero rows → duplicate.\n // If the row is new, RETURNING yields one row → process the event.\n // No TOCTOU race: the UNIQUE constraint on event_id is the single source of truth.\n const [inserted] = await db\n .insert(processedWebhookEvents)\n .values({\n eventId: event.id,\n provider: \"stripe\",\n eventType: event.type,\n })\n .onConflictDoNothing()\n .returning({ id: processedWebhookEvents.id });\n\n if (!inserted) {\n // Row already existed — this is a duplicate delivery\n return c.json({ data: { received: true, duplicate: true } });\n }\n\n // Process the event (first time only)\n if (event.type === \"payment_intent.succeeded\") {\n const data = event.data as Record<string, unknown> | undefined;\n const metadata = data?.metadata as Record<string, unknown> | undefined;\n if (typeof metadata?.orderId === \"string\") {\n await kernel.services.orders.changeStatus(\n {\n orderId: metadata.orderId,\n newStatus: \"confirmed\",\n reason: \"stripe_webhook_payment_intent_succeeded\",\n },\n null,\n );\n }\n }\n\n return c.json({ data: { received: true } });\n });\n\n return router;\n}\n",
|
|
68
|
+
"import { OpenAPIHono } from \"@hono/zod-openapi\";\nimport type { Kernel } from \"../../../runtime/kernel\";\nimport { createWebhookEndpointRoute, listWebhookEndpointsRoute, deleteWebhookEndpointRoute } from \"../schemas/webhooks\";\nimport { type AppEnv, mapErrorToResponse, mapErrorToStatus, requirePerm } from \"../utils\";\n\nexport function webhookRoutes(kernel: Kernel) {\n const router = new OpenAPIHono<AppEnv>();\n\n router.use(\"/*\", requirePerm(\"webhooks:manage\"));\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(createWebhookEndpointRoute, async (c) => {\n const body = c.req.valid(\"json\") as Parameters<typeof kernel.services.webhooks.createEndpoint>[0];\n // Generate a default secret if none provided (Zod schema marks it optional for API convenience)\n if (!body.secret) {\n body.secret = `whsec_${crypto.randomUUID().replace(/-/g, \"\")}`;\n }\n const actor = c.get(\"actor\");\n const result = await kernel.services.webhooks.createEndpoint(body, actor);\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n return c.json({ data: result.value }, 201);\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(listWebhookEndpointsRoute, async (c) => {\n const result = await kernel.services.webhooks.listEndpoints();\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n const sanitized = result.value.map(({ secret: _secret, ...rest }) => rest);\n return c.json({ data: sanitized });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(deleteWebhookEndpointRoute, async (c) => {\n const result = await kernel.services.webhooks.deleteEndpoint(c.req.param(\"id\"));\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n return c.json({ data: { deleted: true } });\n });\n\n return router;\n}\n",
|
|
69
|
+
"import { z, createRoute } from \"@hono/zod-openapi\";\nimport { ErrorSchema, errorResponses } from \"./shared\";\n\n// ─── Request Schema ──────────────────────────────────────────────────────────\n\nexport const CreateWebhookEndpointBodySchema = z.object({\n url: z.string().url().openapi({ example: \"https://example.com/webhooks\" }),\n events: z.array(z.string()).openapi({ example: [\"order.created\", \"order.fulfilled\"] }),\n secret: z.string().optional().openapi({ example: \"whsec_abc123\" }),\n metadata: z.record(z.string(), z.unknown()).optional(),\n}).openapi(\"CreateWebhookEndpointRequest\");\n\n// ─── Route Definitions ──────────────────────────────────────────────────────\n\nexport const listWebhookEndpointsRoute = createRoute({\n method: \"get\",\n path: \"/\",\n tags: [\"Webhooks\"],\n summary: \"List webhook endpoints\",\n responses: {\n 200: {\n content: { \"application/json\": { schema: z.object({ data: z.array(z.record(z.string(), z.unknown())) }) } },\n description: \"Webhook endpoints\",\n },\n },\n});\n\nexport const deleteWebhookEndpointRoute = createRoute({\n method: \"delete\",\n path: \"/{id}\",\n tags: [\"Webhooks\"],\n summary: \"Delete a webhook endpoint\",\n request: {\n params: z.object({\n id: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n }),\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: z.object({ data: z.object({ deleted: z.literal(true) }) }) } },\n description: \"Webhook endpoint deleted.\",\n },\n ...errorResponses,\n },\n});\n\nexport const createWebhookEndpointRoute = createRoute({\n method: \"post\",\n path: \"/\",\n tags: [\"Webhooks\"],\n summary: \"Create a webhook endpoint\",\n description: \"Registers a new webhook endpoint that will receive event notifications.\",\n request: {\n body: {\n content: {\n \"application/json\": { schema: CreateWebhookEndpointBodySchema },\n },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { \"application/json\": { schema: z.object({ data: z.record(z.string(), z.unknown()) }) } },\n description: \"Webhook endpoint created.\",\n },\n ...errorResponses,\n },\n});\n",
|
|
70
|
+
"import { OpenAPIHono } from \"@hono/zod-openapi\";\nimport type { Kernel } from \"../../../runtime/kernel\";\nimport { setBasePriceRoute, createModifierRoute, listPricesRoute } from \"../schemas/pricing\";\nimport { type AppEnv, mapErrorToResponse, mapErrorToStatus, requirePerm } from \"../utils\";\n\nexport function pricingRoutes(kernel: Kernel) {\n const router = new OpenAPIHono<AppEnv>();\n\n router.use(\"/prices\", requirePerm(\"pricing:manage\"));\n\n // @ts-expect-error -- openapi() enforces strict response typing but our handler\n // returns union responses (201 | 400 | 422). The route definition documents the\n // contract; the handler returns dynamic status.\n router.openapi(setBasePriceRoute, async (c) => {\n const actor = c.get(\"actor\");\n const result = await kernel.services.pricing.setBasePrice(c.req.valid(\"json\"), actor);\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n return c.json({ data: result.value }, 201);\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(listPricesRoute, async (c) => {\n const entityId = c.req.query(\"entityId\");\n const variantId = c.req.query(\"variantId\");\n const currency = c.req.query(\"currency\");\n const customerGroupId = c.req.query(\"customerGroupId\");\n\n const result = await kernel.services.pricing.listPrices({\n ...(entityId !== undefined ? { entityId } : {}),\n ...(variantId !== undefined ? { variantId } : {}),\n ...(currency !== undefined ? { currency } : {}),\n ...(customerGroupId !== undefined ? { customerGroupId } : {}),\n });\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n return c.json({ data: result.value });\n });\n\n router.use(\"/modifiers\", requirePerm(\"pricing:manage\"));\n\n // @ts-expect-error -- openapi() enforces strict response typing but our handler\n // returns union responses (201 | 400 | 422). The route definition documents the\n // contract; the handler returns dynamic status.\n router.openapi(createModifierRoute, async (c) => {\n const actor = c.get(\"actor\");\n const result = await kernel.services.pricing.createModifier(c.req.valid(\"json\"), actor);\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n return c.json({ data: result.value }, 201);\n });\n\n return router;\n}\n",
|
|
71
|
+
"import { z, createRoute } from \"@hono/zod-openapi\";\nimport { ErrorSchema, errorResponses } from \"./shared\";\n\n// ─── Request Schemas ────────────────────────────────────────────────────────\n\nimport { SetBasePriceBodySchema, CreateModifierBodySchema } from \"../../../modules/pricing/schemas\";\nexport { SetBasePriceBodySchema, CreateModifierBodySchema };\n\n// ─── Response Schemas ───────────────────────────────────────────────────────\n\nexport const PricingResponseSchema = z.object({\n data: z.record(z.string(), z.unknown()),\n}).openapi(\"PricingResponse\");\n\n// ─── Route Definitions ──────────────────────────────────────────────────────\n\nexport const listPricesRoute = createRoute({\n method: \"get\",\n path: \"/prices\",\n tags: [\"Pricing\"],\n summary: \"List prices\",\n request: {\n query: z.object({\n entityId: z.string().optional(),\n variantId: z.string().optional(),\n currency: z.string().optional(),\n customerGroupId: z.string().optional(),\n }),\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: PricingResponseSchema } },\n description: \"Prices\",\n },\n },\n});\n\nexport const setBasePriceRoute = createRoute({\n method: \"post\",\n path: \"/prices\",\n tags: [\"Pricing\"],\n summary: \"Set a base price for a product or variant\",\n request: {\n body: {\n content: {\n \"application/json\": { schema: SetBasePriceBodySchema },\n },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { \"application/json\": { schema: PricingResponseSchema } },\n description: \"Base price set successfully.\",\n },\n ...errorResponses,\n },\n});\n\nexport const createModifierRoute = createRoute({\n method: \"post\",\n path: \"/modifiers\",\n tags: [\"Pricing\"],\n summary: \"Create a price modifier\",\n request: {\n body: {\n content: {\n \"application/json\": { schema: CreateModifierBodySchema },\n },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { \"application/json\": { schema: PricingResponseSchema } },\n description: \"Price modifier created successfully.\",\n },\n ...errorResponses,\n },\n});\n",
|
|
72
|
+
"import { z } from \"@hono/zod-openapi\";\n\n// ─── Zod Body Schemas (single source of truth) ─────────────────────────────\n\nexport const SetBasePriceBodySchema = z.object({\n entityId: z.string().openapi({ example: \"product-uuid\" }),\n variantId: z.string().optional().openapi({ example: \"variant-uuid\" }),\n currency: z.string().length(3).openapi({ example: \"USD\" }),\n amount: z.number().openapi({ example: 29.99 }),\n customerGroupId: z.string().optional(),\n minQuantity: z.number().int().optional(),\n maxQuantity: z.number().int().optional(),\n validFrom: z.coerce.date().optional(),\n validUntil: z.coerce.date().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n}).openapi(\"SetBasePriceRequest\");\n\nexport const CreateModifierBodySchema = z.object({\n name: z.string().openapi({ example: \"Summer Sale\" }),\n type: z.enum([\"percentage_discount\", \"fixed_discount\", \"markup\", \"override\"]).openapi({ example: \"percentage_discount\" }),\n value: z.number().openapi({ example: 10 }),\n priority: z.number().int().optional(),\n entityId: z.string().optional(),\n variantId: z.string().optional(),\n customerGroupId: z.string().optional(),\n currency: z.string().length(3).optional().openapi({ example: \"USD\" }),\n minQuantity: z.number().int().optional(),\n maxQuantity: z.number().int().optional(),\n conditions: z.record(z.string(), z.unknown()).optional(),\n validFrom: z.coerce.date().optional(),\n validUntil: z.coerce.date().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n}).openapi(\"CreateModifierRequest\");\n\n// ─── Derived Input Types ────────────────────────────────────────────────────\n\nexport type SetBasePriceInput = z.infer<typeof SetBasePriceBodySchema>;\nexport type CreatePriceModifierInput = z.infer<typeof CreateModifierBodySchema>;\n",
|
|
73
|
+
"import { OpenAPIHono } from \"@hono/zod-openapi\";\nimport { rateLimiter } from \"hono-rate-limiter\";\nimport type { Kernel } from \"../../../runtime/kernel\";\nimport { createPromotionRoute, validatePromotionRoute, deactivatePromotionRoute, listActivePromotionsRoute } from \"../schemas/promotions\";\nimport { type AppEnv, mapErrorToResponse, mapErrorToStatus, requirePerm } from \"../utils\";\nimport { resolveOrgId } from \"../../../auth/org\";\n\nexport function promotionRoutes(kernel: Kernel) {\n const router = new OpenAPIHono<AppEnv>();\n\n // Rate limit promo code validation — prevents brute-force code enumeration\n router.use(\n \"/validate\",\n rateLimiter({\n windowMs: 60 * 1000,\n limit: 10,\n keyGenerator: (c) => {\n const raw = c.req.raw as unknown as { socket?: { remoteAddress?: string } };\n return raw?.socket?.remoteAddress ?? \"unknown\";\n },\n }),\n );\n\n router.use(\"/\", requirePerm(\"promotions:manage\"));\n\n // @ts-expect-error -- openapi() enforces strict response typing but our handler\n // returns union responses (201 | 400 | 422). The route definition documents the\n // contract; the handler returns dynamic status.\n router.openapi(createPromotionRoute, async (c) => {\n const body = c.req.valid(\"json\");\n const actor = c.get(\"actor\");\n const result = await kernel.services.promotions.create(body, actor);\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n return c.json({ data: result.value }, 201);\n });\n\n // List active promotions — requires auth\n router.use(\"/active\", requirePerm(\"promotions:read\"));\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(listActivePromotionsRoute, async (_c) => {\n const actor = _c.get(\"actor\");\n const result = await kernel.services.promotions.listActive(actor);\n if (!result.ok) {\n return _c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n return _c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi() enforces strict response typing but our handler\n // returns union responses (200 | 400 | 404). The route definition documents the\n // contract; the handler returns dynamic status.\n router.openapi(validatePromotionRoute, async (c) => {\n const payload = c.req.valid(\"json\");\n const actor = c.get(\"actor\");\n const orgId = resolveOrgId(actor);\n\n const result = await kernel.services.promotions.validate(payload.code, {\n orgId,\n currency: payload.currency,\n subtotal: payload.subtotal,\n lineItems: payload.lineItems,\n ...(payload.customerId !== undefined ? { customerId: payload.customerId } : {}),\n ...(payload.customerGroupIds !== undefined ? { customerGroupIds: payload.customerGroupIds } : {}),\n });\n\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n\n return c.json({ data: result.value });\n });\n\n router.use(\"/:id/deactivate\", requirePerm(\"promotions:manage\"));\n\n // @ts-expect-error -- openapi() enforces strict response typing but our handler\n // returns union responses (200 | 400 | 404). The route definition documents the\n // contract; the handler returns dynamic status.\n router.openapi(deactivatePromotionRoute, async (c) => {\n const actor = c.get(\"actor\");\n const orgId = resolveOrgId(actor);\n const result = await kernel.services.promotions.deactivate(orgId, c.req.param(\"id\"));\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n return c.json({ data: result.value });\n });\n\n return router;\n}\n",
|
|
74
|
+
"import { z, createRoute } from \"@hono/zod-openapi\";\nimport { ErrorSchema, errorResponses, UuidParamSchema } from \"./shared\";\n\n// ─── Request Schemas ────────────────────────────────────────────────────────\n\nimport { CreatePromotionBodySchema } from \"../../../modules/promotions/schemas\";\nexport { CreatePromotionBodySchema };\n\nexport const ValidatePromotionBodySchema = z.object({\n code: z.string().openapi({ example: \"SUMMER10\" }),\n currency: z.string().length(3).openapi({ example: \"USD\" }),\n subtotal: z.number().openapi({ example: 100 }),\n lineItems: z.array(z.object({\n entityId: z.string(),\n entityType: z.string(),\n quantity: z.number().int(),\n unitPrice: z.number(),\n totalPrice: z.number(),\n })),\n customerId: z.string().optional(),\n customerGroupIds: z.array(z.string()).optional(),\n}).openapi(\"ValidatePromotionRequest\");\n\n// ─── Response Schemas ───────────────────────────────────────────────────────\n\nexport const PromotionResponseSchema = z.object({\n data: z.record(z.string(), z.unknown()),\n}).openapi(\"PromotionResponse\");\n\n// ─── Path Params ────────────────────────────────────────────────────────────\n\nconst PromotionIdParam = z.object({\n id: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n});\n\n// ─── Route Definitions ──────────────────────────────────────────────────────\n\nexport const listActivePromotionsRoute = createRoute({\n method: \"get\",\n path: \"/\",\n tags: [\"Promotions\"],\n summary: \"List active promotions\",\n responses: {\n 200: {\n content: { \"application/json\": { schema: PromotionResponseSchema } },\n description: \"Active promotions\",\n },\n },\n});\n\nexport const createPromotionRoute = createRoute({\n method: \"post\",\n path: \"/\",\n tags: [\"Promotions\"],\n summary: \"Create a new promotion\",\n request: {\n body: {\n content: {\n \"application/json\": { schema: CreatePromotionBodySchema },\n },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { \"application/json\": { schema: PromotionResponseSchema } },\n description: \"Promotion created successfully.\",\n },\n ...errorResponses,\n },\n});\n\nexport const validatePromotionRoute = createRoute({\n method: \"post\",\n path: \"/validate\",\n tags: [\"Promotions\"],\n summary: \"Validate a promotion code against a cart\",\n request: {\n body: {\n content: {\n \"application/json\": { schema: ValidatePromotionBodySchema },\n },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: PromotionResponseSchema } },\n description: \"Promotion validation result.\",\n },\n ...errorResponses,\n },\n});\n\nexport const deactivatePromotionRoute = createRoute({\n method: \"post\",\n path: \"/{id}/deactivate\",\n tags: [\"Promotions\"],\n summary: \"Deactivate a promotion\",\n request: {\n params: PromotionIdParam,\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: PromotionResponseSchema } },\n description: \"Promotion deactivated.\",\n },\n ...errorResponses,\n },\n});\n",
|
|
75
|
+
"import { z } from \"@hono/zod-openapi\";\n\n// ─── Zod Body Schemas (single source of truth) ─────────────────────────────\n\nexport const CreatePromotionBodySchema = z.object({\n name: z.string().openapi({ example: \"Summer Sale\" }),\n type: z.enum([\n \"percentage_off_order\",\n \"fixed_off_order\",\n \"percentage_off_item\",\n \"fixed_off_item\",\n \"free_shipping\",\n \"buy_x_get_y\",\n ]).openapi({ example: \"percentage_off_order\" }),\n value: z.number().openapi({ example: 10 }),\n code: z.string().optional().openapi({ example: \"SUMMER10\" }),\n buyQuantity: z.number().int().optional(),\n getQuantity: z.number().int().optional(),\n isAutomatic: z.boolean().optional(),\n isActive: z.boolean().optional(),\n priority: z.number().int().optional(),\n conditions: z.object({\n minimumOrderValue: z.number().optional(),\n minimumQuantity: z.number().int().optional(),\n entityTypes: z.array(z.string()).optional(),\n categories: z.array(z.string()).optional(),\n customerGroups: z.array(z.string()).optional(),\n }).optional(),\n usageLimitTotal: z.number().int().optional(),\n usageLimitPerCustomer: z.number().int().optional(),\n validFrom: z.coerce.date().optional(),\n validUntil: z.coerce.date().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n}).openapi(\"CreatePromotionRequest\");\n\n// ─── Derived Input Types ────────────────────────────────────────────────────\n\nexport type CreatePromotionInput = z.infer<typeof CreatePromotionBodySchema>;\n",
|
|
76
|
+
"import { OpenAPIHono } from \"@hono/zod-openapi\";\nimport type { Kernel } from \"../../../runtime/kernel\";\nimport { searchRoute, suggestRoute } from \"../schemas/search\";\nimport { type AppEnv, mapErrorToResponse, mapErrorToStatus } from \"../utils\";\n\nexport function searchRoutes(kernel: Kernel) {\n const router = new OpenAPIHono<AppEnv>();\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(searchRoute, async (c) => {\n const q = c.req.query(\"q\") ?? \"\";\n const type = c.req.query(\"type\");\n const category = c.req.query(\"category\");\n const brand = c.req.query(\"brand\");\n const status = c.req.query(\"status\");\n const page = Number.parseInt(c.req.query(\"page\") ?? \"1\", 10);\n const limit = Number.parseInt(c.req.query(\"limit\") ?? \"20\", 10);\n const facets = (c.req.query(\"facets\") ?? \"\")\n .split(\",\")\n .map((facet) => facet.trim())\n .filter(Boolean);\n\n const result = await kernel.services.search.query({\n query: q,\n page,\n limit,\n filters: {\n ...(type ? { type } : {}),\n ...(category ? { category } : {}),\n ...(brand ? { brand } : {}),\n ...(status ? { status } : {}),\n },\n ...(facets.length > 0 ? { facets } : {}),\n }, { actor: c.get(\"actor\"), tx: null, requestId: \"\" });\n\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n\n return c.json({\n data: result.value.hits,\n meta: {\n total: result.value.total,\n page: result.value.page,\n limit: result.value.limit,\n facets: result.value.facets,\n },\n });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(suggestRoute, async (c) => {\n const prefix = c.req.query(\"prefix\") ?? \"\";\n const type = c.req.query(\"type\");\n const limit = Number.parseInt(c.req.query(\"limit\") ?? \"10\", 10);\n\n const result = await kernel.services.search.suggest({\n prefix,\n ...(type ? { type } : {}),\n limit,\n }, { actor: c.get(\"actor\"), tx: null, requestId: \"\" });\n\n if (!result.ok) {\n return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));\n }\n\n return c.json({ data: result.value });\n });\n\n return router;\n}\n",
|
|
77
|
+
"import { z, createRoute } from \"@hono/zod-openapi\";\nimport { CatalogEntitySchema } from \"./responses\";\n\n// ─── Route Definitions ──────────────────────────────────────────────────────\n\nexport const searchRoute = createRoute({\n method: \"get\",\n path: \"/\",\n tags: [\"Search\"],\n summary: \"Search catalog entities\",\n request: {\n query: z.object({\n q: z.string().optional(),\n type: z.string().optional(),\n category: z.string().optional(),\n brand: z.string().optional(),\n status: z.string().optional(),\n page: z.string().optional(),\n limit: z.string().optional(),\n facets: z.string().optional(),\n }),\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: z.object({\n data: z.array(CatalogEntitySchema),\n meta: z.object({\n pagination: z.object({\n page: z.number(),\n limit: z.number(),\n total: z.number().optional(),\n }),\n }).optional(),\n }) } },\n description: \"Search results\",\n },\n },\n});\n\nexport const suggestRoute = createRoute({\n method: \"get\",\n path: \"/suggest\",\n tags: [\"Search\"],\n summary: \"Get search suggestions\",\n request: {\n query: z.object({\n prefix: z.string().optional(),\n type: z.string().optional(),\n limit: z.string().optional(),\n }),\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: z.object({ data: z.array(z.object({ id: z.string(), slug: z.string(), title: z.string().optional() })) }) } },\n description: \"Suggestions\",\n },\n },\n});\n",
|
|
78
|
+
"import { OpenAPIHono } from \"@hono/zod-openapi\";\nimport type { Kernel } from \"../../../runtime/kernel\";\nimport { listAuditRoute, listEntityAuditRoute } from \"../schemas/audit\";\nimport { type AppEnv, requirePerm } from \"../utils\";\nimport { resolveOrgId } from \"../../../auth/org\";\n\nexport function auditRoutes(kernel: Kernel) {\n const router = new OpenAPIHono<AppEnv>();\n\n /**\n * GET /api/audit\n * List audit entries with optional filters.\n */\n router.use(\"/\", requirePerm(\"audit:read\"));\n\n router.openapi(listAuditRoute, async (c) => {\n const actor = c.get(\"actor\");\n const orgId = resolveOrgId(actor);\n const entries = await kernel.services.audit.list({\n organizationId: orgId,\n entityType: c.req.query(\"entityType\"),\n entityId: c.req.query(\"entityId\"),\n event: c.req.query(\"event\"),\n actorId: c.req.query(\"actorId\"),\n from: c.req.query(\"from\") ? new Date(c.req.query(\"from\")!) : undefined,\n to: c.req.query(\"to\") ? new Date(c.req.query(\"to\")!) : undefined,\n limit: c.req.query(\"limit\") ? Number(c.req.query(\"limit\")) : 50,\n });\n return c.json({ data: entries });\n });\n\n /**\n * GET /api/audit/:entityType/:entityId\n * List audit history for a specific entity.\n */\n router.use(\"/:entityType/:entityId\", requirePerm(\"audit:read\"));\n\n router.openapi(listEntityAuditRoute, async (c) => {\n const actor = c.get(\"actor\");\n const orgId = resolveOrgId(actor);\n const entries = await kernel.services.audit.listForEntity({\n organizationId: orgId,\n entityType: c.req.param(\"entityType\"),\n entityId: c.req.param(\"entityId\"),\n });\n return c.json({ data: entries });\n });\n\n return router;\n}\n",
|
|
79
|
+
"import { z, createRoute } from \"@hono/zod-openapi\";\n\n// ─── Route Definitions ──────────────────────────────────────────────────────\n\nexport const listAuditRoute = createRoute({\n method: \"get\",\n path: \"/\",\n tags: [\"Audit\"],\n summary: \"List audit entries\",\n request: {\n query: z.object({\n entityType: z.string().optional(),\n entityId: z.string().optional(),\n event: z.string().optional(),\n actorId: z.string().optional(),\n from: z.string().optional(),\n to: z.string().optional(),\n limit: z.string().optional(),\n }),\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: z.object({ data: z.array(z.record(z.string(), z.unknown())) }) } },\n description: \"Audit entries\",\n },\n },\n});\n\nexport const listEntityAuditRoute = createRoute({\n method: \"get\",\n path: \"/{entityType}/{entityId}\",\n tags: [\"Audit\"],\n summary: \"List audit history for a specific entity\",\n request: {\n params: z.object({\n entityType: z.string().min(1).openapi({ example: \"order\" }),\n entityId: z.string().min(1).openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n }),\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: z.object({ data: z.array(z.record(z.string(), z.unknown())) }) } },\n description: \"Entity audit history\",\n },\n },\n});\n",
|
|
80
|
+
"import { OpenAPIHono } from \"@hono/zod-openapi\";\nimport { eq, and, desc } from \"drizzle-orm\";\nimport type { PgDatabase, PgQueryResultHKT } from \"drizzle-orm/pg-core\";\nimport type { Kernel } from \"../../../runtime/kernel\";\nimport { commerceJobs } from \"../../../kernel/jobs/schema\";\nimport { listFailedJobsRoute, retryJobRoute } from \"../schemas/admin-jobs\";\nimport { type AppEnv, requirePerm } from \"../utils\";\nimport { resolveOrgId } from \"../../../auth/org\";\n\ntype Db = PgDatabase<PgQueryResultHKT, Record<string, unknown>>;\n\nexport function adminJobRoutes(kernel: Kernel) {\n const router = new OpenAPIHono<AppEnv>();\n const db = kernel.database.db as Db;\n\n router.use(\"/jobs/failed\", requirePerm(\"jobs:admin\"));\n\n router.openapi(listFailedJobsRoute, async (c) => {\n const actor = c.get(\"actor\");\n const orgId = resolveOrgId(actor);\n const limit = Math.min(Number(c.req.query(\"limit\") ?? \"50\"), 100);\n const conditions = [eq(commerceJobs.status, \"failed\")];\n // Scope to org unless wildcard admin\n if (!actor?.permissions?.includes(\"*:*\")) {\n conditions.push(eq(commerceJobs.organizationId, orgId));\n }\n const failed = await db.select()\n .from(commerceJobs)\n .where(and(...conditions))\n .orderBy(desc(commerceJobs.completedAt))\n .limit(limit);\n return c.json({ data: failed });\n });\n\n router.use(\"/jobs/:id/retry\", requirePerm(\"jobs:admin\"));\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(retryJobRoute, async (c) => {\n const actor = c.get(\"actor\");\n const orgId = resolveOrgId(actor);\n const id = c.req.param(\"id\");\n const conditions = [eq(commerceJobs.id, id)];\n // Scope to org unless wildcard admin\n if (!actor?.permissions?.includes(\"*:*\")) {\n conditions.push(eq(commerceJobs.organizationId, orgId));\n }\n const result = await db.update(commerceJobs)\n .set({ status: \"pending\", attempts: 0, error: null, waitUntil: null, updatedAt: new Date() })\n .where(and(...conditions))\n .returning();\n if (result.length === 0) {\n return c.json({ error: { code: \"NOT_FOUND\", message: \"Job not found.\" } }, 404);\n }\n return c.json({ data: { retried: true } });\n });\n\n return router;\n}\n",
|
|
81
|
+
"import { z, createRoute } from \"@hono/zod-openapi\";\nimport { JobListResponse } from \"./responses\";\n\n// ─── Route Definitions ──────────────────────────────────────────────────────\n\nexport const listFailedJobsRoute = createRoute({\n method: \"get\",\n path: \"/jobs/failed\",\n tags: [\"Admin Jobs\"],\n summary: \"List failed jobs\",\n request: {\n query: z.object({\n limit: z.string().optional(),\n }),\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: JobListResponse } },\n description: \"Failed jobs\",\n },\n },\n});\n\nexport const retryJobRoute = createRoute({\n method: \"post\",\n path: \"/jobs/{id}/retry\",\n tags: [\"Admin Jobs\"],\n summary: \"Retry a failed job\",\n request: {\n params: z.object({\n id: z.string().min(1).openapi({ example: \"job-uuid\" }),\n }),\n },\n responses: {\n 200: {\n content: { \"application/json\": { schema: z.object({ data: z.object({ retried: z.literal(true) }) }) } },\n description: \"Job retried\",\n },\n },\n});\n",
|
|
82
|
+
"import { OpenAPIHono } from \"@hono/zod-openapi\";\nimport type { Kernel } from \"../../runtime/kernel\";\nimport { assertPermission } from \"../../auth/permissions\";\nimport type { Actor } from \"../../auth/types\";\nimport type { AppEnv } from \"./utils\";\nimport {\n getProfileRoute,\n listAddressesRoute,\n listCustomerOrdersRoute,\n getCustomerOrderRoute,\n getOrderTrackingRoute,\n getOrderDownloadsRoute,\n listCoursesRoute,\n deleteAddressRoute,\n reorderRoute,\n updateProfileRoute,\n createAddressRoute,\n} from \"./schemas/customer-portal\";\nimport { isUUID, mapErrorToStatus } from \"./utils\";\n\nexport function createCustomerPortalRoutes(kernel: Kernel) {\n const router = new OpenAPIHono<AppEnv>();\n\n router.use(\"*\", async (c, next) => {\n if (!c.get(\"actor\")) {\n return c.json(\n { error: { code: \"FORBIDDEN\", message: \"Authentication required.\" } },\n 401,\n );\n }\n await next();\n });\n\n /**\n * Resolves an actor whose userId is the customer profile UUID (not the Better Auth user ID).\n * Required so that `assertOwnership(actor, order.customerId)` compares UUIDs correctly,\n * since orders.customer_id stores the customer profile UUID, not the Better Auth string ID.\n */\n async function resolveCustomerActor(actor: Actor): Promise<Actor | null> {\n const customer = await kernel.services.customers.getByUserId(actor.userId, actor);\n if (!customer.ok) return null;\n return { ...actor, userId: customer.value.id };\n }\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(getProfileRoute, async (c) => {\n const actor = c.get(\"actor\") as Actor;\n const customer = await kernel.services.customers.getByUserId(actor.userId, actor);\n if (!customer.ok) return c.json({ error: customer.error }, 404);\n return c.json({ data: customer.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(updateProfileRoute, async (c) => {\n const actor = c.get(\"actor\") as Actor;\n assertPermission(actor, \"customers:update:self\");\n const result = await kernel.services.customers.updateByUserId(\n actor.userId,\n c.req.valid(\"json\") as Parameters<typeof kernel.services.customers.updateByUserId>[1],\n actor,\n );\n if (!result.ok) return c.json({ error: result.error }, 422);\n return c.json({ data: result.value });\n });\n\n router.openapi(listAddressesRoute, async (c) => {\n const actor = c.get(\"actor\") as Actor;\n const addresses = await kernel.services.customers.getAddresses(\n actor.userId,\n actor,\n );\n return c.json({ data: addresses.ok ? addresses.value : [] });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(createAddressRoute, async (c) => {\n const actor = c.get(\"actor\") as Actor;\n const result = await kernel.services.customers.addAddress(\n actor.userId,\n c.req.valid(\"json\") as Parameters<typeof kernel.services.customers.addAddress>[1],\n actor,\n );\n if (!result.ok) return c.json({ error: result.error }, 422);\n return c.json({ data: result.value }, 201);\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(deleteAddressRoute, async (c) => {\n const actor = c.get(\"actor\") as Actor;\n const result = await kernel.services.customers.deleteAddress(\n actor.userId,\n c.req.param(\"id\"),\n actor,\n );\n if (!result.ok) return c.json({ error: result.error }, 404);\n return c.json({ data: { deleted: true } });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(listCustomerOrdersRoute, async (c) => {\n const actor = c.get(\"actor\") as Actor;\n const status = c.req.query(\"status\");\n // Resolve customer profile UUID from Better Auth userId\n const customerResult = await kernel.services.customers.getByUserId(actor.userId, actor);\n if (!customerResult.ok) return c.json({ data: [], meta: { total: 0, page: 1, limit: 20, totalPages: 0 } });\n const result = await kernel.services.orders.listByCustomer(customerResult.value.id, {\n page: Number.parseInt(c.req.query(\"page\") ?? \"1\", 10),\n limit: Number.parseInt(c.req.query(\"limit\") ?? \"20\", 10),\n ...(status !== undefined ? { status } : {}),\n });\n if (!result.ok) return c.json({ error: result.error }, 500);\n return c.json({ data: result.value.items, meta: result.value.pagination });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(getCustomerOrderRoute, async (c) => {\n const actor = c.get(\"actor\") as Actor;\n const id = c.req.param(\"idOrNumber\");\n const customerActor = await resolveCustomerActor(actor);\n if (!customerActor) return c.json({ error: { code: \"NOT_FOUND\", message: \"Customer profile not found.\" } }, 404);\n const result = isUUID(id)\n ? await kernel.services.orders.getById(id, customerActor)\n : await kernel.services.orders.getByNumber(id, customerActor);\n\n if (!result.ok)\n return c.json({ error: result.error }, mapErrorToStatus(result.error));\n return c.json({ data: result.value });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(getOrderTrackingRoute, async (c) => {\n const actor = c.get(\"actor\") as Actor;\n const id = c.req.param(\"idOrNumber\");\n const customerActor = await resolveCustomerActor(actor);\n if (!customerActor) return c.json({ error: { code: \"NOT_FOUND\", message: \"Customer profile not found.\" } }, 404);\n\n const orderResult = isUUID(id)\n ? await kernel.services.orders.getById(id, customerActor)\n : await kernel.services.orders.getByNumber(id, customerActor);\n\n if (!orderResult.ok) {\n return c.json(\n { error: orderResult.error },\n mapErrorToStatus(orderResult.error),\n );\n }\n\n const fulfillments = await kernel.services.fulfillment.getByOrderId(\n orderResult.value.id,\n );\n if (!fulfillments.ok) return c.json({ error: fulfillments.error }, 500);\n\n return c.json({\n data: fulfillments.value.map((item) => ({\n fulfillmentId: item.id,\n status: item.status,\n carrier: item.carrier ?? null,\n trackingNumber: item.trackingNumber ?? null,\n trackingUrl: item.trackingUrl ?? null,\n estimatedDelivery: item.estimatedDelivery ?? null,\n shippedAt: item.shippedAt ?? null,\n deliveredAt: item.deliveredAt ?? null,\n lineItems: item.lineItems,\n })),\n });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(getOrderDownloadsRoute, async (c) => {\n const actor = c.get(\"actor\") as Actor;\n const customerActor = await resolveCustomerActor(actor);\n if (!customerActor) return c.json({ error: { code: \"NOT_FOUND\", message: \"Customer profile not found.\" } }, 404);\n const orderResult = await kernel.services.orders.getById(\n c.req.param(\"orderId\"),\n customerActor,\n );\n if (!orderResult.ok) {\n return c.json(\n { error: orderResult.error },\n mapErrorToStatus(orderResult.error),\n );\n }\n\n const digitalItems = orderResult.value.lineItems.filter(\n (lineItem) => lineItem.entityType === \"digitalDownload\",\n );\n\n const downloads = await Promise.all(\n digitalItems.map(async (lineItem) => {\n const result = await kernel.services.fulfillment.getDownloadUrl(\n orderResult.value.id,\n lineItem.id,\n actor.userId,\n actor,\n );\n\n return {\n lineItemId: lineItem.id,\n title: lineItem.title,\n downloadUrl: result.ok ? result.value.url : null,\n downloadsRemaining: result.ok ? result.value.remaining : 0,\n expiresAt: result.ok ? result.value.expiresAt : null,\n };\n }),\n );\n\n return c.json({ data: downloads });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(listCoursesRoute, async (c) => {\n const actor = c.get(\"actor\") as Actor;\n const result = await kernel.services.fulfillment.getDigitalAccess(\n actor.userId,\n \"course\",\n );\n if (!result.ok) return c.json({ error: result.error }, 500);\n\n return c.json({\n data: result.value.map((item) => ({\n entityId: item.entityId,\n title: item.title,\n accessGrantedAt: item.grantedAt,\n accessExpiresAt: item.expiresAt,\n isActive: item.isActive,\n orderId: item.orderId,\n })),\n });\n });\n\n // @ts-expect-error -- openapi handler union return type\n router.openapi(reorderRoute, async (c) => {\n const actor = c.get(\"actor\") as Actor;\n const customerActor = await resolveCustomerActor(actor);\n if (!customerActor) return c.json({ error: { code: \"NOT_FOUND\", message: \"Customer profile not found.\" } }, 404);\n const orderResult = await kernel.services.orders.getById(\n c.req.param(\"orderId\"),\n customerActor,\n );\n if (!orderResult.ok) {\n return c.json(\n { error: orderResult.error },\n mapErrorToStatus(orderResult.error),\n );\n }\n\n const cartResult = await kernel.services.cart.create(\n {\n customerId: actor.userId,\n currency: orderResult.value.currency,\n },\n actor,\n );\n\n if (!cartResult.ok) return c.json({ error: cartResult.error }, 500);\n\n const addResults = await Promise.all(\n orderResult.value.lineItems.map((lineItem) =>\n kernel.services.cart.addItem(\n {\n cartId: cartResult.value.id,\n entityId: lineItem.entityId,\n quantity: lineItem.quantity,\n unitPriceSnapshot: lineItem.unitPrice,\n currency: orderResult.value.currency,\n ...(lineItem.variantId != null\n ? { variantId: lineItem.variantId }\n : {}),\n },\n actor,\n ),\n ),\n );\n\n const failures = addResults\n .map((item, index) =>\n item.ok\n ? null\n : {\n item: orderResult.value.lineItems[index]?.title ?? \"unknown\",\n reason: item.error.message,\n },\n )\n .filter(Boolean);\n\n return c.json(\n {\n data: {\n cartId: cartResult.value.id,\n itemsAdded: addResults.filter((item) => item.ok).length,\n itemsFailed: failures,\n },\n },\n 201,\n );\n });\n\n return router;\n}\n",
|
|
83
|
+
"import { CommerceForbiddenError } from \"../kernel/errors\";\nimport type { Actor } from \"./types\";\n\nexport function assertPermission(actor: Actor | null, required: string): void {\n if (!actor) {\n throw new CommerceForbiddenError(\"Authentication required.\");\n }\n\n if (actor.permissions.includes(\"*:*\")) return;\n\n const [resource] = required.split(\":\");\n if (resource && actor.permissions.includes(`${resource}:*`)) return;\n if (actor.permissions.includes(required)) return;\n\n throw new CommerceForbiddenError(\n `Permission \"${required}\" is required. Your role \"${actor.role}\" does not include this permission.`,\n );\n}\n\nexport function assertOwnership(actor: Actor | null, resourceOwnerId: string | null): void {\n if (!actor) {\n throw new CommerceForbiddenError(\"Authentication required.\");\n }\n if (actor.permissions.includes(\"*:*\")) return;\n if (actor.userId !== resourceOwnerId) {\n throw new CommerceForbiddenError(\"You do not have access to this resource.\");\n }\n}\n",
|
|
84
|
+
"import { z, createRoute } from \"@hono/zod-openapi\";\nimport { errorResponses } from \"./shared\";\nimport { CustomerResponse, OrderResponse, OrderListResponse, CustomerAddressListResponse, CartResponse } from \"./responses\";\n\nconst GenericDataResponse = z.object({ data: z.record(z.string(), z.unknown()) });\n\n// ─── GET Route Definitions ─────────────────────────────────────────────────\n\nexport const getProfileRoute = createRoute({\n method: \"get\",\n path: \"/profile\",\n tags: [\"Customer Portal\"],\n summary: \"Get customer profile\",\n responses: {\n 200: { content: { \"application/json\": { schema: CustomerResponse } }, description: \"Customer profile\" },\n ...errorResponses,\n },\n});\n\nexport const listAddressesRoute = createRoute({\n method: \"get\",\n path: \"/addresses\",\n tags: [\"Customer Portal\"],\n summary: \"List customer addresses\",\n responses: {\n 200: { content: { \"application/json\": { schema: CustomerAddressListResponse } }, description: \"Addresses\" },\n },\n});\n\nexport const listCustomerOrdersRoute = createRoute({\n method: \"get\",\n path: \"/orders\",\n tags: [\"Customer Portal\"],\n summary: \"List customer orders\",\n request: {\n query: z.object({\n status: z.string().optional(),\n page: z.string().optional(),\n limit: z.string().optional(),\n }),\n },\n responses: {\n 200: { content: { \"application/json\": { schema: OrderListResponse } }, description: \"Orders\" },\n },\n});\n\nexport const getCustomerOrderRoute = createRoute({\n method: \"get\",\n path: \"/orders/{idOrNumber}\",\n tags: [\"Customer Portal\"],\n summary: \"Get a specific customer order\",\n request: {\n params: z.object({\n idOrNumber: z.string().min(1).openapi({ example: \"ORD-001\" }),\n }),\n },\n responses: {\n 200: { content: { \"application/json\": { schema: OrderResponse } }, description: \"Order details\" },\n ...errorResponses,\n },\n});\n\nexport const getOrderTrackingRoute = createRoute({\n method: \"get\",\n path: \"/orders/{idOrNumber}/tracking\",\n tags: [\"Customer Portal\"],\n summary: \"Get tracking info for an order\",\n request: {\n params: z.object({\n idOrNumber: z.string().min(1).openapi({ example: \"ORD-001\" }),\n }),\n },\n responses: {\n 200: { content: { \"application/json\": { schema: GenericDataResponse } }, description: \"Tracking info\" },\n ...errorResponses,\n },\n});\n\nexport const getOrderDownloadsRoute = createRoute({\n method: \"get\",\n path: \"/orders/{orderId}/downloads\",\n tags: [\"Customer Portal\"],\n summary: \"Get digital downloads for an order\",\n request: {\n params: z.object({\n orderId: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n }),\n },\n responses: {\n 200: { content: { \"application/json\": { schema: GenericDataResponse } }, description: \"Downloads\" },\n ...errorResponses,\n },\n});\n\nexport const listCoursesRoute = createRoute({\n method: \"get\",\n path: \"/courses\",\n tags: [\"Customer Portal\"],\n summary: \"List customer course access\",\n responses: {\n 200: { content: { \"application/json\": { schema: GenericDataResponse } }, description: \"Courses\" },\n },\n});\n\n// ─── DELETE Route Definitions ──────────────────────────────────────────────\n\nexport const deleteAddressRoute = createRoute({\n method: \"delete\",\n path: \"/addresses/{id}\",\n tags: [\"Customer Portal\"],\n summary: \"Delete a customer address\",\n request: {\n params: z.object({\n id: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n }),\n },\n responses: {\n 200: { content: { \"application/json\": { schema: z.object({ data: z.object({ deleted: z.literal(true) }) }) } }, description: \"Deleted\" },\n ...errorResponses,\n },\n});\n\n// ─── POST Route Definitions (no body or special) ───────────────────────────\n\nexport const reorderRoute = createRoute({\n method: \"post\",\n path: \"/orders/{orderId}/reorder\",\n tags: [\"Customer Portal\"],\n summary: \"Reorder items from a previous order\",\n request: {\n params: z.object({\n orderId: z.uuid().openapi({ example: \"550e8400-e29b-41d4-a716-446655440000\" }),\n }),\n },\n responses: {\n 201: { content: { \"application/json\": { schema: CartResponse } }, description: \"Reorder cart created\" },\n ...errorResponses,\n },\n});\n\n// ─── Mutation Route Definitions ─────────────────────────────────────────────\n\nconst UpdateProfileBodySchema = z.object({\n firstName: z.string().optional(),\n lastName: z.string().optional(),\n phone: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n}).openapi(\"UpdateProfileBody\");\n\nconst CreateAddressBodySchema = z.object({\n type: z.enum([\"shipping\", \"billing\"]).openapi({ example: \"shipping\" }),\n firstName: z.string().openapi({ example: \"John\" }),\n lastName: z.string().openapi({ example: \"Doe\" }),\n line1: z.string().openapi({ example: \"123 Main St\" }),\n line2: z.string().optional(),\n city: z.string().openapi({ example: \"New York\" }),\n state: z.string().optional(),\n postalCode: z.string().optional(),\n country: z.string().openapi({ example: \"US\" }),\n phone: z.string().optional(),\n}).openapi(\"CreateAddressBody\");\n\nexport const updateProfileRoute = createRoute({\n method: \"patch\",\n path: \"/profile\",\n tags: [\"Customer Portal\"],\n summary: \"Update customer profile\",\n request: {\n body: {\n content: { \"application/json\": { schema: UpdateProfileBodySchema } },\n required: true,\n },\n },\n responses: {\n 200: { content: { \"application/json\": { schema: CustomerResponse } }, description: \"Updated\" },\n ...errorResponses,\n },\n});\n\nexport const createAddressRoute = createRoute({\n method: \"post\",\n path: \"/addresses\",\n tags: [\"Customer Portal\"],\n summary: \"Create a customer address\",\n request: {\n body: {\n content: { \"application/json\": { schema: CreateAddressBodySchema } },\n required: true,\n },\n },\n responses: {\n 201: { content: { \"application/json\": { schema: GenericDataResponse } }, description: \"Created\" },\n ...errorResponses,\n },\n});\n",
|
|
85
|
+
"export type HookHandler = (...args: never[]) => unknown;\n\ntype HookEntry = {\n prepended: HookHandler[];\n configured: HookHandler[];\n appended: HookHandler[];\n};\n\nexport class HookRegistry {\n private registry = new Map<string, HookEntry>();\n private logger?: { error: (obj: Record<string, unknown>, msg: string) => void };\n\n registerConfigHooks(hookName: string, handlers: HookHandler[]): void {\n this.ensureEntry(hookName);\n this.registry.get(hookName)!.configured = [...handlers];\n }\n\n append(hookName: string, handler: HookHandler): void {\n this.ensureEntry(hookName);\n this.registry.get(hookName)!.appended.push(handler);\n }\n\n prepend(hookName: string, handler: HookHandler): void {\n this.ensureEntry(hookName);\n this.registry.get(hookName)!.prepended.push(handler);\n }\n\n resolve(hookName: string): HookHandler[] {\n const entry = this.registry.get(hookName);\n if (!entry) return [];\n return [...entry.prepended, ...entry.configured, ...entry.appended];\n }\n\n /**\n * Emit a plugin event to all registered listeners.\n *\n * Unlike the before/after hook pattern (which transforms data through\n * a pipeline), emit is fire-and-forget notification. Errors in handlers\n * are caught and logged but do not propagate to the emitter.\n *\n * Usage:\n * kernel.hooks.emit(\"production.afterComplete\", { orderId, quantity });\n *\n * Any plugin can listen:\n * hooks: () => [{ key: \"production.afterComplete\", handler: async (payload) => { ... } }]\n */\n setLogger(logger: { error: (obj: Record<string, unknown>, msg: string) => void }): void {\n this.logger = logger;\n }\n\n async emit(key: string, payload: unknown): Promise<void> {\n const handlers = this.resolve(key);\n for (const handler of handlers) {\n try {\n await (handler as (payload: unknown) => unknown)(payload);\n } catch (err) {\n this.logger?.error(\n { err, hookKey: key },\n `Event handler failed for \"${key}\"`,\n );\n }\n }\n }\n\n private ensureEntry(hookName: string): void {\n if (!this.registry.has(hookName)) {\n this.registry.set(hookName, {\n prepended: [],\n configured: [],\n appended: [],\n });\n }\n }\n}\n",
|
|
86
|
+
"export interface DatabaseAdapter<TDatabase = unknown, TTransaction = unknown> {\n provider: string;\n db: TDatabase;\n transaction<T>(fn: (tx: TTransaction) => Promise<T>): Promise<T>;\n}\n\nexport interface DatabaseConnectionFactoryInput {\n adapter: DatabaseAdapter;\n}\n\nexport function createDatabaseConnection(input: DatabaseConnectionFactoryInput): DatabaseAdapter {\n return input.adapter;\n}\n",
|
|
87
|
+
"import { resolveOrgId } from \"../../auth/org\";\nimport { assertPermission } from \"../../auth/permissions\";\nimport type { Actor } from \"../../auth/types\";\nimport type { CommerceConfig } from \"../../config/types\";\nimport {\n CommerceConflictError,\n CommerceNotFoundError,\n CommerceValidationError,\n toCommerceError,\n} from \"../../kernel/errors\";\nimport { runAfterHooks, runBeforeHooks } from \"../../kernel/hooks/executor\";\nimport { createHookContext } from \"../../kernel/hooks/create-context\";\nimport type {\n AfterHook,\n BeforeHook,\n HookContext,\n} from \"../../kernel/hooks/types\";\nimport type { HookRegistry } from \"../../kernel/hooks/registry\";\nimport { Err, Ok, type Result } from \"../../kernel/result\";\nimport { createLogger } from \"../../utils/logger\";\nimport { paginate, type Pagination } from \"../../utils/pagination\";\nimport type { TxContext } from \"../../kernel/database/tx-context\";\nimport {\n CatalogRepository,\n type SellableEntity,\n type SellableAttribute,\n type SellableCustomField,\n type SellableCustomFieldInsert,\n type Category,\n type EntityCategory,\n type EntityBrand,\n type Brand,\n type OptionType,\n type OptionValue,\n type Variant,\n} from \"./repository\";\n\n// ─── Re-exported schema-derived types ────────────────────────────────────────\nexport type {\n CreateEntityInput,\n UpdateEntityInput,\n CreateCategoryInput,\n UpdateCategoryInput,\n CreateBrandInput,\n UpdateBrandInput,\n CreateOptionTypeInput,\n CreateOptionValueInput,\n CreateVariantInput,\n} from \"./schemas\";\n\nimport type {\n CreateEntityInput,\n UpdateEntityInput,\n CreateCategoryInput,\n UpdateCategoryInput,\n CreateBrandInput,\n UpdateBrandInput,\n CreateOptionTypeInput,\n CreateOptionValueInput,\n CreateVariantInput,\n} from \"./schemas\";\n\n// ─── Hand-written types (not derivable from a single z.infer) ───────────────\n\nexport interface SetAttributesInput {\n title: string;\n subtitle?: string;\n description?: string;\n richDescription?: unknown;\n seoTitle?: string;\n seoDescription?: string;\n}\n\nexport interface ListParams {\n filter?: {\n type?: string;\n status?: string;\n category?: string;\n brand?: string;\n customField?: {\n fieldName: string;\n value: unknown;\n };\n };\n sort?: {\n field: \"createdAt\" | \"updatedAt\" | \"slug\";\n direction: \"asc\" | \"desc\";\n };\n pagination?: {\n page: number;\n limit: number;\n };\n}\n\nexport interface GetOptions {\n includeAttributes?: boolean | { locales: string[] };\n includeVariants?: boolean;\n includeOptionTypes?: boolean;\n includePricing?: boolean;\n includeInventory?: boolean;\n includeMedia?: boolean;\n includeCategories?: boolean;\n includeBrands?: boolean;\n}\n\nexport interface VariantMatrixRule {\n include?: string[][];\n exclude?: string[][];\n}\n\nexport type VariantGenerationStrategy =\n | { mode: \"all\" }\n | { mode: \"manual\"; combinations: string[][] }\n | { mode: \"matrix\"; matrix: VariantMatrixRule };\n\nexport interface CatalogEntityHydrated extends SellableEntity {\n attributes?: SellableAttribute[];\n variants?: Array<Variant & { optionValueIds: string[] }>;\n optionTypes?: Array<OptionType & { values: OptionValue[] }>;\n categories?: EntityCategory[];\n brands?: EntityBrand[];\n media?: Array<{ mediaAssetId: string; role: string; variantId?: string }>;\n}\n\nexport interface CatalogService {\n create(\n input: CreateEntityInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogEntityHydrated>>;\n update(\n id: string,\n input: UpdateEntityInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogEntityHydrated>>;\n delete(\n id: string,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<void>>;\n getById(\n id: string,\n options?: GetOptions,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogEntityHydrated>>;\n getBySlug(\n slug: string,\n options?: GetOptions,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogEntityHydrated>>;\n list(params: ListParams, actor?: Actor | null, ctx?: TxContext): Promise<Result<CatalogListResult>>;\n publish(\n id: string,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogEntityHydrated>>;\n archive(\n id: string,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogEntityHydrated>>;\n discontinue(\n id: string,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogEntityHydrated>>;\n setAttributes(\n entityId: string,\n locale: string,\n attrs: SetAttributesInput,\n ctx?: TxContext,\n ): Promise<Result<void>>;\n getAttributes(\n entityId: string,\n locale: string,\n ctx?: TxContext,\n ): Promise<Result<SellableAttribute>>;\n listCategories(ctx?: TxContext): Promise<Result<CategorySummary[]>>;\n createCategory(\n input: CreateCategoryInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CategorySummary>>;\n updateCategory(\n id: string,\n input: UpdateCategoryInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CategorySummary>>;\n deleteCategory(\n id: string,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<void>>;\n addToCategory(\n entityId: string,\n categoryId: string,\n ctx?: TxContext,\n ): Promise<Result<void>>;\n removeFromCategory(\n entityId: string,\n categoryId: string,\n ctx?: TxContext,\n ): Promise<Result<void>>;\n listBrands(ctx?: TxContext): Promise<Result<Brand[]>>;\n createBrand(\n input: CreateBrandInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Brand>>;\n updateBrand(\n id: string,\n input: UpdateBrandInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Brand>>;\n deleteBrand(\n id: string,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<void>>;\n addToBrand(\n entityId: string,\n brandId: string,\n ctx?: TxContext,\n ): Promise<Result<void>>;\n removeFromBrand(\n entityId: string,\n brandId: string,\n ctx?: TxContext,\n ): Promise<Result<void>>;\n createOptionType(\n input: CreateOptionTypeInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<OptionType>>;\n createOptionValue(\n input: CreateOptionValueInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<OptionValue>>;\n createVariant(\n input: CreateVariantInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Variant>>;\n generateVariants(\n entityId: string,\n strategy: VariantGenerationStrategy,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Variant[]>>;\n}\n\nexport interface CatalogServiceDeps {\n repository: CatalogRepository;\n hooks: HookRegistry;\n config: CommerceConfig;\n services: Record<string, unknown>;\n}\n\ntype CatalogListResult = {\n items: CatalogEntityHydrated[];\n pagination: Pagination;\n};\n\ntype CategorySummary = {\n id: string;\n parentId?: string | null;\n slug: string;\n sortOrder: number;\n metadata: Record<string, unknown>;\n};\n\ntype CatalogCreateBeforeHook = BeforeHook<CreateEntityInput>;\ntype CatalogCreateAfterHook = AfterHook<SellableEntity>;\ntype CatalogUpdateBeforeHook = BeforeHook<UpdateEntityInput>;\ntype CatalogUpdateAfterHook = AfterHook<SellableEntity>;\ntype CatalogReadHookInput = {\n id?: string;\n slug?: string;\n options?: GetOptions;\n};\ntype CatalogReadBeforeHook = BeforeHook<CatalogReadHookInput>;\ntype CatalogReadAfterHook = AfterHook<CatalogEntityHydrated>;\ntype CatalogListBeforeHook = BeforeHook<ListParams>;\ntype CatalogListAfterHook = AfterHook<CatalogListResult>;\n\nfunction cartesian<T>(arrays: T[][]): T[][] {\n return arrays.reduce<T[][]>(\n (acc, values) =>\n acc.flatMap((entry) => values.map((value) => [...entry, value])),\n [[]],\n );\n}\n\n/**\n * Helper to extract the value from a SellableCustomField based on its type.\n */\nfunction getCustomFieldValue(field: SellableCustomField): unknown {\n switch (field.fieldType) {\n case \"text\":\n case \"relation\":\n return field.textValue;\n case \"number\":\n return field.numberValue;\n case \"boolean\":\n return field.booleanValue;\n case \"date\":\n return field.dateValue;\n case \"json\":\n return field.jsonValue;\n default:\n return null;\n }\n}\n\nexport class CatalogServiceImpl implements CatalogService {\n private readonly repo: CatalogRepository;\n\n constructor(private deps: CatalogServiceDeps) {\n this.repo = deps.repository;\n }\n\n private async validateAndCreateCustomFields(\n entityId: string,\n entityType: string,\n customFields: Record<string, unknown> | undefined,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n if (!customFields) return Ok(undefined);\n const entityConfig = this.deps.config.entities?.[entityType];\n if (!entityConfig) return Ok(undefined);\n\n const definitionMap = new Map(entityConfig.fields.map((f) => [f.name, f]));\n\n for (const [name, value] of Object.entries(customFields)) {\n const def = definitionMap.get(name);\n if (!def) {\n return Err(\n new CommerceValidationError(`Unknown custom field: ${name}`),\n );\n }\n\n const type = def.type;\n let valid = false;\n switch (type) {\n case \"text\":\n case \"relation\":\n case \"select\":\n valid = typeof value === \"string\";\n break;\n case \"number\":\n valid = typeof value === \"number\";\n break;\n case \"boolean\":\n valid = typeof value === \"boolean\";\n break;\n case \"date\":\n valid = typeof value === \"string\" || value instanceof Date;\n break;\n case \"json\":\n valid = typeof value === \"object\";\n break;\n default:\n valid = false;\n }\n\n if (!valid) {\n return Err(\n new CommerceValidationError(\n `Custom field ${name} expected type ${type}.`,\n ),\n );\n }\n\n const fieldType = (\n type === \"select\" ? \"text\" : type\n ) as SellableCustomField[\"fieldType\"];\n const insertData: SellableCustomFieldInsert = {\n entityId,\n fieldName: name,\n fieldType,\n };\n\n switch (fieldType) {\n case \"text\":\n case \"relation\":\n insertData.textValue = value as string;\n break;\n case \"number\":\n insertData.numberValue = value as number;\n break;\n case \"boolean\":\n insertData.booleanValue = value as boolean;\n break;\n case \"date\":\n insertData.dateValue =\n value instanceof Date ? value : new Date(value as string);\n break;\n case \"json\":\n insertData.jsonValue = value;\n break;\n }\n\n await this.repo.createCustomField(insertData, ctx);\n }\n\n return Ok(undefined);\n }\n\n private async hydrateEntity(\n entity: SellableEntity,\n options?: GetOptions,\n ctx?: TxContext,\n ): Promise<CatalogEntityHydrated> {\n const hydrated: CatalogEntityHydrated = { ...entity };\n\n if (options?.includeAttributes) {\n const attrs = await this.repo.findAttributesByEntityId(entity.id, ctx);\n if (typeof options.includeAttributes === \"object\") {\n hydrated.attributes = attrs.filter(\n (a) =>\n options.includeAttributes &&\n typeof options.includeAttributes === \"object\" &&\n options.includeAttributes.locales.includes(a.locale),\n );\n } else {\n hydrated.attributes = attrs;\n }\n }\n\n if (options?.includeVariants) {\n const entityVariants = await this.repo.findVariantsByEntityId(\n entity.id,\n ctx,\n );\n const variantsWithOptions = await Promise.all(\n entityVariants.map(async (variant) => {\n const optionValues = await this.repo.findVariantOptionValues(\n variant.id,\n ctx,\n );\n return {\n ...variant,\n optionValueIds: optionValues.map((vov) => vov.optionValueId),\n };\n }),\n );\n hydrated.variants = variantsWithOptions;\n }\n\n if (options?.includeOptionTypes) {\n const entityOptionTypes = await this.repo.findOptionTypesByEntityId(\n entity.id,\n ctx,\n );\n hydrated.optionTypes = await Promise.all(\n entityOptionTypes.map(async (ot) => {\n const values = await this.repo.findOptionValuesByTypeId(ot.id, ctx);\n return { ...ot, values };\n }),\n );\n }\n\n if (options?.includeCategories) {\n hydrated.categories = await this.repo.findEntityCategories(\n entity.id,\n ctx,\n );\n }\n\n if (options?.includeBrands) {\n hydrated.brands = await this.repo.findEntityBrands(entity.id, ctx);\n }\n\n if (options?.includeMedia) {\n // TODO: integrate with MediaRepository when media service is refactored\n hydrated.media = [];\n }\n\n return hydrated;\n }\n\n async create(\n input: CreateEntityInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogEntityHydrated>> {\n try {\n assertPermission(actor, \"catalog:create\");\n\n const orgId = resolveOrgId(actor);\n\n const existingBySlug = await this.repo.findEntityBySlug(orgId, input.slug, ctx);\n if (existingBySlug) {\n return Err(\n new CommerceConflictError(\n `Entity with slug ${input.slug} already exists.`,\n ),\n );\n }\n\n const beforeHooks = this.deps.hooks.resolve(\n \"catalog.beforeCreate\",\n ) as CatalogCreateBeforeHook[];\n const afterHooks = this.deps.hooks.resolve(\n \"catalog.afterCreate\",\n ) as CatalogCreateAfterHook[];\n const logger = createLogger(\"catalog.create\");\n const context: HookContext = createHookContext({\n actor,\n tx: ctx?.tx ?? null,\n logger,\n services: this.deps.services,\n });\n\n const processedInput = await runBeforeHooks(\n beforeHooks,\n input,\n \"create\",\n context,\n );\n const entity = await this.repo.createEntity(\n {\n organizationId: orgId,\n type: processedInput.type,\n slug: processedInput.slug,\n status: \"draft\",\n isVisible: false,\n metadata: processedInput.metadata ?? {},\n },\n ctx,\n );\n\n if (processedInput.attributes) {\n await this.repo.createAttribute(\n {\n entityId: entity.id,\n locale: processedInput.attributes.locale ?? \"en\",\n title: processedInput.attributes.title,\n subtitle: processedInput.attributes.subtitle,\n description: processedInput.attributes.description,\n richDescription: processedInput.attributes.richDescription,\n seoTitle: processedInput.attributes.seoTitle,\n seoDescription: processedInput.attributes.seoDescription,\n },\n ctx,\n );\n }\n\n const customFieldsResult = await this.validateAndCreateCustomFields(\n entity.id,\n entity.type,\n processedInput.customFields,\n ctx,\n );\n if (!customFieldsResult.ok) return customFieldsResult;\n\n const hookReport = await runAfterHooks(\n afterHooks,\n null,\n entity,\n \"create\",\n context,\n );\n const hydrated = await this.hydrateEntity(entity, undefined, ctx);\n return Ok(\n hydrated,\n hookReport.hasErrors ? { hookErrors: hookReport.errors } : undefined,\n );\n } catch (error) {\n return Err(toCommerceError(error));\n }\n }\n\n async update(\n id: string,\n input: UpdateEntityInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogEntityHydrated>> {\n try {\n assertPermission(actor, \"catalog:update\");\n const existing = await this.repo.findEntityById(id, ctx);\n if (!existing) return Err(new CommerceNotFoundError(\"Entity not found.\"));\n\n const beforeHooks = this.deps.hooks.resolve(\n \"catalog.beforeUpdate\",\n ) as CatalogUpdateBeforeHook[];\n const afterHooks = this.deps.hooks.resolve(\n \"catalog.afterUpdate\",\n ) as CatalogUpdateAfterHook[];\n const context: HookContext = createHookContext({\n actor,\n tx: ctx?.tx ?? null,\n logger: createLogger(\"catalog.update\"),\n services: this.deps.services,\n });\n const processed = await runBeforeHooks(\n beforeHooks,\n input,\n \"update\",\n context,\n );\n\n const updated = await this.repo.updateEntity(\n id,\n {\n ...(processed.slug !== undefined ? { slug: processed.slug } : {}),\n ...(processed.status !== undefined\n ? { status: processed.status as SellableEntity[\"status\"] }\n : {}),\n ...(processed.metadata !== undefined\n ? { metadata: processed.metadata }\n : {}),\n ...(processed.isVisible !== undefined\n ? { isVisible: processed.isVisible }\n : {}),\n },\n ctx,\n );\n\n if (!updated) return Err(new CommerceNotFoundError(\"Entity not found.\"));\n\n const hookReport = await runAfterHooks(\n afterHooks,\n existing,\n updated,\n \"update\",\n context,\n );\n const hydrated = await this.hydrateEntity(updated, undefined, ctx);\n return Ok(\n hydrated,\n hookReport.hasErrors ? { hookErrors: hookReport.errors } : undefined,\n );\n } catch (error) {\n return Err(toCommerceError(error));\n }\n }\n\n async delete(\n id: string,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n try {\n assertPermission(actor, \"catalog:delete\");\n const existing = await this.repo.findEntityById(id, ctx);\n if (!existing) return Err(new CommerceNotFoundError(\"Entity not found.\"));\n\n // Clean up related data (cascade handles most, but be explicit)\n await this.repo.deleteAttributesByEntityId(id, ctx);\n await this.repo.deleteCustomFieldsByEntityId(id, ctx);\n await this.repo.deleteEntityCategoriesByEntityId(id, ctx);\n await this.repo.deleteEntityBrandsByEntityId(id, ctx);\n await this.repo.deleteVariantOptionValuesByEntityId(id, ctx);\n await this.repo.deleteVariantsByEntityId(id, ctx);\n await this.repo.deleteEntity(id, ctx);\n\n return Ok(undefined);\n } catch (error) {\n return Err(toCommerceError(error));\n }\n }\n\n async getById(\n id: string,\n options?: GetOptions,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogEntityHydrated>> {\n const context: HookContext = createHookContext({\n actor: actor ?? null,\n tx: ctx?.tx ?? null,\n logger: createLogger(\"catalog.read\"),\n services: this.deps.services,\n });\n const beforeHooks = this.deps.hooks.resolve(\n \"catalog.beforeRead\",\n ) as CatalogReadBeforeHook[];\n const afterHooks = this.deps.hooks.resolve(\n \"catalog.afterRead\",\n ) as CatalogReadAfterHook[];\n const readInput: CatalogReadHookInput = {\n id,\n ...(options !== undefined ? { options } : {}),\n };\n const processed = await runBeforeHooks(\n beforeHooks,\n readInput,\n \"read\",\n context,\n );\n\n const entity = await this.repo.findEntityById(processed.id ?? id, ctx);\n if (!entity) return Err(new CommerceNotFoundError(\"Entity not found.\"));\n\n // Org boundary check — prevent cross-org access\n if (actor && entity.organizationId) {\n const orgId = resolveOrgId(actor);\n if (entity.organizationId !== orgId) {\n return Err(new CommerceNotFoundError(\"Entity not found.\"));\n }\n }\n\n const result = await this.hydrateEntity(\n entity,\n processed.options ?? options,\n ctx,\n );\n const report = await runAfterHooks(\n afterHooks,\n null,\n result,\n \"read\",\n context,\n );\n return Ok(\n result,\n report.hasErrors ? { hookErrors: report.errors } : undefined,\n );\n }\n\n async getBySlug(\n slug: string,\n options?: GetOptions,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogEntityHydrated>> {\n const context: HookContext = createHookContext({\n actor: actor ?? null,\n tx: ctx?.tx ?? null,\n logger: createLogger(\"catalog.read\"),\n services: this.deps.services,\n });\n const beforeHooks = this.deps.hooks.resolve(\n \"catalog.beforeRead\",\n ) as CatalogReadBeforeHook[];\n const afterHooks = this.deps.hooks.resolve(\n \"catalog.afterRead\",\n ) as CatalogReadAfterHook[];\n const readInput: CatalogReadHookInput = {\n slug,\n ...(options !== undefined ? { options } : {}),\n };\n const processed = await runBeforeHooks(\n beforeHooks,\n readInput,\n \"read\",\n context,\n );\n\n const resolvedSlug = processed.slug ?? slug;\n const orgId = resolveOrgId(actor ?? null);\n const entity = await this.repo.findEntityBySlug(orgId, resolvedSlug, ctx);\n if (!entity) return Err(new CommerceNotFoundError(\"Entity not found.\"));\n\n const result = await this.hydrateEntity(\n entity,\n processed.options ?? options,\n ctx,\n );\n const report = await runAfterHooks(\n afterHooks,\n null,\n result,\n \"read\",\n context,\n );\n return Ok(\n result,\n report.hasErrors ? { hookErrors: report.errors } : undefined,\n );\n }\n\n async list(\n params: ListParams,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogListResult>> {\n const resolvedActor = actor ?? ctx?.actor ?? null;\n const context: HookContext = createHookContext({\n actor: resolvedActor,\n tx: ctx?.tx ?? null,\n logger: createLogger(\"catalog.list\"),\n services: this.deps.services,\n });\n const beforeHooks = this.deps.hooks.resolve(\n \"catalog.beforeList\",\n ) as CatalogListBeforeHook[];\n const afterHooks = this.deps.hooks.resolve(\n \"catalog.afterList\",\n ) as CatalogListAfterHook[];\n const processed = await runBeforeHooks(\n beforeHooks,\n params,\n \"list\",\n context,\n );\n\n const listOrgId = resolveOrgId(resolvedActor);\n let entities = await this.repo.findEntities(\n listOrgId,\n {\n ...(processed.filter?.type ? { type: processed.filter.type } : {}),\n ...(processed.filter?.status\n ? { status: processed.filter.status }\n : {}),\n },\n ctx,\n );\n\n // Category filter (M1 fix: validate input format, return error if not found)\n if (processed.filter?.category) {\n const catInput = processed.filter.category;\n const isUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n let category = await this.repo.findCategoryBySlug(listOrgId, catInput, ctx);\n\n if (!category && isUUID.test(catInput)) {\n category = await this.repo.findCategoryById(catInput, ctx);\n }\n\n if (!category) {\n return Err(\n new CommerceValidationError(`Category not found: \"${catInput}\".`),\n );\n }\n\n const entityIds = await this.repo.findEntitiesByCategory(\n category.id,\n ctx,\n );\n const entityIdSet = new Set(entityIds);\n entities = entities.filter((e) => entityIdSet.has(e.id));\n }\n\n // Brand filter\n if (processed.filter?.brand) {\n let brand = await this.repo.findBrandBySlug(listOrgId, processed.filter.brand, ctx);\n if (!brand) {\n brand = await this.repo.findBrandById(processed.filter.brand, ctx);\n }\n if (brand) {\n const brandEntityIds: string[] = [];\n for (const entity of entities) {\n const entityBrands = await this.repo.findEntityBrands(entity.id, ctx);\n if (entityBrands.some((eb) => eb.brandId === brand!.id)) {\n brandEntityIds.push(entity.id);\n }\n }\n const brandEntitySet = new Set(brandEntityIds);\n entities = entities.filter((e) => brandEntitySet.has(e.id));\n }\n }\n\n // Custom field filter\n if (processed.filter?.customField) {\n const filteredIds: string[] = [];\n for (const entity of entities) {\n const fields = await this.repo.findCustomFieldsByEntityId(\n entity.id,\n ctx,\n );\n const matches = fields.some((field) => {\n if (field.fieldName !== processed.filter?.customField?.fieldName)\n return false;\n return (\n getCustomFieldValue(field) === processed.filter.customField.value\n );\n });\n if (matches) filteredIds.push(entity.id);\n }\n const filteredSet = new Set(filteredIds);\n entities = entities.filter((e) => filteredSet.has(e.id));\n }\n\n // Sorting\n if (processed.sort) {\n const direction = processed.sort.direction === \"asc\" ? 1 : -1;\n entities.sort((a, b) => {\n const first = a[processed.sort!.field];\n const second = b[processed.sort!.field];\n if (first instanceof Date && second instanceof Date) {\n return (first.getTime() - second.getTime()) * direction;\n }\n return String(first).localeCompare(String(second)) * direction;\n });\n }\n\n const page = processed.pagination?.page ?? 1;\n const limit = processed.pagination?.limit ?? 20;\n const paged = paginate(entities, page, limit);\n\n const hydratedItems = await Promise.all(\n paged.items.map((entity) => this.hydrateEntity(entity, undefined, ctx)),\n );\n\n const result = { items: hydratedItems, pagination: paged.pagination };\n const report = await runAfterHooks(\n afterHooks,\n null,\n result,\n \"list\",\n context,\n );\n return Ok(\n result,\n report.hasErrors ? { hookErrors: report.errors } : undefined,\n );\n }\n\n private async changeStatus(\n id: string,\n status: SellableEntity[\"status\"],\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogEntityHydrated>> {\n const entity = await this.repo.findEntityById(id, ctx);\n if (!entity) return Err(new CommerceNotFoundError(\"Entity not found.\"));\n\n assertPermission(actor, \"catalog:update\");\n\n const updateData: Partial<SellableEntity> = { status };\n if (status === \"active\") {\n updateData.publishedAt = new Date();\n updateData.isVisible = true;\n }\n\n const updated = await this.repo.updateEntity(id, updateData, ctx);\n if (!updated) return Err(new CommerceNotFoundError(\"Entity not found.\"));\n\n return Ok(await this.hydrateEntity(updated, undefined, ctx));\n }\n\n publish(\n id: string,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogEntityHydrated>> {\n return this.changeStatus(id, \"active\", actor, ctx);\n }\n\n archive(\n id: string,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogEntityHydrated>> {\n return this.changeStatus(id, \"archived\", actor, ctx);\n }\n\n discontinue(\n id: string,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CatalogEntityHydrated>> {\n return this.changeStatus(id, \"discontinued\", actor, ctx);\n }\n\n async setAttributes(\n entityId: string,\n locale: string,\n attrs: SetAttributesInput,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n const entity = await this.repo.findEntityById(entityId, ctx);\n if (!entity) return Err(new CommerceNotFoundError(\"Entity not found.\"));\n\n await this.repo.upsertAttribute(\n entityId,\n locale,\n {\n title: attrs.title,\n subtitle: attrs.subtitle,\n description: attrs.description,\n richDescription: attrs.richDescription,\n seoTitle: attrs.seoTitle,\n seoDescription: attrs.seoDescription,\n },\n ctx,\n );\n\n return Ok(undefined);\n }\n\n async getAttributes(\n entityId: string,\n locale: string,\n ctx?: TxContext,\n ): Promise<Result<SellableAttribute>> {\n const attr = await this.repo.findAttributeByLocale(entityId, locale, ctx);\n if (!attr)\n return Err(\n new CommerceNotFoundError(`Attributes for locale ${locale} not found.`),\n );\n return Ok(attr);\n }\n\n async listCategories(ctx?: TxContext): Promise<Result<CategorySummary[]>> {\n const allCategories = await this.repo.findAllCategories(resolveOrgId(ctx?.actor ?? null), ctx);\n const sorted = allCategories.sort(\n (a, b) => a.sortOrder - b.sortOrder || a.slug.localeCompare(b.slug),\n );\n return Ok(\n sorted.map((c) => ({\n id: c.id,\n parentId: c.parentId,\n slug: c.slug,\n sortOrder: c.sortOrder,\n metadata: c.metadata ?? {},\n })),\n );\n }\n\n async createCategory(\n input: CreateCategoryInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CategorySummary>> {\n assertPermission(actor, \"catalog:update\");\n\n if (input.id) {\n const existingById = await this.repo.findCategoryById(input.id, ctx);\n if (existingById) {\n return Err(\n new CommerceConflictError(\n `Category with id ${input.id} already exists.`,\n ),\n );\n }\n }\n\n const orgId = resolveOrgId(actor);\n const existingBySlug = await this.repo.findCategoryBySlug(orgId, input.slug, ctx);\n if (existingBySlug) {\n return Err(\n new CommerceConflictError(\n `Category with slug ${input.slug} already exists.`,\n ),\n );\n }\n\n const category = await this.repo.createCategory(\n {\n organizationId: orgId,\n ...(input.id ? { id: input.id } : {}),\n slug: input.slug,\n sortOrder: input.sortOrder ?? 0,\n metadata: input.metadata ?? {},\n ...(input.parentId !== undefined ? { parentId: input.parentId } : {}),\n },\n ctx,\n );\n\n return Ok({\n id: category.id,\n parentId: category.parentId,\n slug: category.slug,\n sortOrder: category.sortOrder,\n metadata: category.metadata ?? {},\n });\n }\n\n async updateCategory(\n id: string,\n input: UpdateCategoryInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CategorySummary>> {\n assertPermission(actor, \"catalog:update\");\n\n const existing = await this.repo.findCategoryById(id, ctx);\n if (!existing) return Err(new CommerceNotFoundError(\"Category not found.\"));\n\n if (input.slug) {\n const catOrgId = resolveOrgId(actor);\n const existingBySlug = await this.repo.findCategoryBySlug(\n catOrgId,\n input.slug,\n ctx,\n );\n if (existingBySlug && existingBySlug.id !== id) {\n return Err(\n new CommerceConflictError(\n `Category with slug ${input.slug} already exists.`,\n ),\n );\n }\n }\n\n const updated = await this.repo.updateCategory(\n id,\n {\n ...(input.slug !== undefined ? { slug: input.slug } : {}),\n ...(input.sortOrder !== undefined\n ? { sortOrder: input.sortOrder }\n : {}),\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n ...(input.parentId !== undefined ? { parentId: input.parentId } : {}),\n },\n ctx,\n );\n\n if (!updated) return Err(new CommerceNotFoundError(\"Category not found.\"));\n\n return Ok({\n id: updated.id,\n parentId: updated.parentId,\n slug: updated.slug,\n sortOrder: updated.sortOrder,\n metadata: updated.metadata ?? {},\n });\n }\n\n async deleteCategory(\n id: string,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n assertPermission(actor, \"catalog:update\");\n\n const existing = await this.repo.findCategoryById(id, ctx);\n if (!existing) return Err(new CommerceNotFoundError(\"Category not found.\"));\n\n await this.repo.deleteEntityCategoriesByCategoryId(id, ctx);\n await this.repo.deleteCategory(id, ctx);\n\n return Ok(undefined);\n }\n\n async addToCategory(\n entityId: string,\n categoryId: string,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n const entity = await this.repo.findEntityById(entityId, ctx);\n if (!entity) return Err(new CommerceNotFoundError(\"Entity not found.\"));\n\n const addCatOrgId = resolveOrgId(ctx?.actor ?? null);\n const isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(categoryId);\n let category = isUuid ? await this.repo.findCategoryById(categoryId, ctx) : null;\n if (!category) {\n category = await this.repo.findCategoryBySlug(addCatOrgId, categoryId, ctx);\n }\n if (!category) {\n category = await this.repo.createCategory(\n {\n organizationId: addCatOrgId,\n slug: categoryId,\n sortOrder: 0,\n metadata: {},\n },\n ctx,\n );\n }\n\n await this.repo.addEntityToCategory(entityId, category.id, 0, ctx);\n return Ok(undefined);\n }\n\n async removeFromCategory(\n entityId: string,\n categoryId: string,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n const isCatUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(categoryId);\n let category = isCatUuid ? await this.repo.findCategoryById(categoryId, ctx) : null;\n if (!category) {\n category = await this.repo.findCategoryBySlug(resolveOrgId(ctx?.actor ?? null), categoryId, ctx);\n }\n const resolvedCategoryId = category?.id ?? categoryId;\n\n const removed = await this.repo.removeEntityFromCategory(\n entityId,\n resolvedCategoryId,\n ctx,\n );\n if (!removed)\n return Err(new CommerceNotFoundError(\"Category assignment not found.\"));\n return Ok(undefined);\n }\n\n async listBrands(ctx?: TxContext): Promise<Result<Brand[]>> {\n const allBrands = await this.repo.findAllBrands(resolveOrgId(ctx?.actor ?? null), ctx);\n return Ok(\n allBrands.sort((a, b) => a.displayName.localeCompare(b.displayName)),\n );\n }\n\n async createBrand(\n input: CreateBrandInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Brand>> {\n assertPermission(actor, \"catalog:update\");\n\n if (input.id) {\n const existingById = await this.repo.findBrandById(input.id, ctx);\n if (existingById) {\n return Err(\n new CommerceConflictError(\n `Brand with id ${input.id} already exists.`,\n ),\n );\n }\n }\n\n const orgId = resolveOrgId(actor);\n const existingBySlug = await this.repo.findBrandBySlug(orgId, input.slug, ctx);\n if (existingBySlug) {\n return Err(\n new CommerceConflictError(\n `Brand with slug ${input.slug} already exists.`,\n ),\n );\n }\n\n return Ok(\n await this.repo.createBrand(\n {\n organizationId: orgId,\n ...(input.id ? { id: input.id } : {}),\n slug: input.slug,\n displayName: input.displayName,\n metadata: input.metadata ?? {},\n },\n ctx,\n ),\n );\n }\n\n async updateBrand(\n id: string,\n input: UpdateBrandInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Brand>> {\n assertPermission(actor, \"catalog:update\");\n\n const existing = await this.repo.findBrandById(id, ctx);\n if (!existing) return Err(new CommerceNotFoundError(\"Brand not found.\"));\n\n if (input.slug) {\n const brandOrgId = resolveOrgId(actor);\n const existingBySlug = await this.repo.findBrandBySlug(brandOrgId, input.slug, ctx);\n if (existingBySlug && existingBySlug.id !== id) {\n return Err(\n new CommerceConflictError(\n `Brand with slug ${input.slug} already exists.`,\n ),\n );\n }\n }\n\n const updated = await this.repo.updateBrand(\n id,\n {\n ...(input.slug !== undefined ? { slug: input.slug } : {}),\n ...(input.displayName !== undefined\n ? { displayName: input.displayName }\n : {}),\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n },\n ctx,\n );\n\n if (!updated) return Err(new CommerceNotFoundError(\"Brand not found.\"));\n return Ok(updated);\n }\n\n async deleteBrand(\n id: string,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n assertPermission(actor, \"catalog:update\");\n\n const existing = await this.repo.findBrandById(id, ctx);\n if (!existing) return Err(new CommerceNotFoundError(\"Brand not found.\"));\n\n await this.repo.deleteEntityBrandsByBrandId(id, ctx);\n await this.repo.deleteBrand(id, ctx);\n\n return Ok(undefined);\n }\n\n async addToBrand(\n entityId: string,\n brandId: string,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n const entity = await this.repo.findEntityById(entityId, ctx);\n if (!entity) return Err(new CommerceNotFoundError(\"Entity not found.\"));\n\n const addBrandOrgId = resolveOrgId(ctx?.actor ?? null);\n const isBrandUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(brandId);\n let brand = isBrandUuid ? await this.repo.findBrandById(brandId, ctx) : null;\n if (!brand) {\n brand = await this.repo.findBrandBySlug(addBrandOrgId, brandId, ctx);\n }\n if (!brand) {\n brand = await this.repo.createBrand(\n {\n organizationId: addBrandOrgId,\n slug: brandId,\n displayName: brandId,\n metadata: {},\n },\n ctx,\n );\n }\n\n await this.repo.addEntityToBrand(entityId, brand.id, 0, ctx);\n return Ok(undefined);\n }\n\n async removeFromBrand(\n entityId: string,\n brandId: string,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n const isBrUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(brandId);\n let brand = isBrUuid ? await this.repo.findBrandById(brandId, ctx) : null;\n if (!brand) {\n brand = await this.repo.findBrandBySlug(resolveOrgId(ctx?.actor ?? null), brandId, ctx);\n }\n const resolvedBrandId = brand?.id ?? brandId;\n\n const removed = await this.repo.removeEntityFromBrand(\n entityId,\n resolvedBrandId,\n ctx,\n );\n if (!removed)\n return Err(new CommerceNotFoundError(\"Brand assignment not found.\"));\n return Ok(undefined);\n }\n\n async createOptionType(\n input: CreateOptionTypeInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<OptionType>> {\n assertPermission(actor, \"catalog:update\");\n\n const entity = await this.repo.findEntityById(input.entityId, ctx);\n if (!entity) return Err(new CommerceNotFoundError(\"Entity not found.\"));\n\n const optionType = await this.repo.createOptionType(\n {\n entityId: input.entityId,\n name: input.name,\n displayName: input.name,\n sortOrder: 0,\n },\n ctx,\n );\n\n // Create initial option values if provided\n if (input.values) {\n for (const value of input.values) {\n await this.repo.createOptionValue(\n {\n optionTypeId: optionType.id,\n value,\n displayValue: value,\n sortOrder: 0,\n metadata: {},\n },\n ctx,\n );\n }\n }\n\n return Ok(optionType);\n }\n\n async createOptionValue(\n input: CreateOptionValueInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<OptionValue>> {\n assertPermission(actor, \"catalog:update\");\n\n const optionType = await this.repo.findOptionTypeById(\n input.optionTypeId,\n ctx,\n );\n if (!optionType)\n return Err(new CommerceNotFoundError(\"Option type not found.\"));\n\n return Ok(\n await this.repo.createOptionValue(\n {\n optionTypeId: input.optionTypeId,\n value: input.value,\n displayValue: input.value,\n sortOrder: 0,\n metadata: {},\n },\n ctx,\n ),\n );\n }\n\n async createVariant(\n input: CreateVariantInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Variant>> {\n assertPermission(actor, \"catalog:update\");\n\n const entity = await this.repo.findEntityById(input.entityId, ctx);\n if (!entity) return Err(new CommerceNotFoundError(\"Entity not found.\"));\n\n // Resolve options record (e.g. { Color: \"Red\" }) into option value IDs\n const entityOptionTypes = await this.repo.findOptionTypesByEntityId(\n input.entityId,\n ctx,\n );\n const optionValueIds: string[] = [];\n for (const [optName, optVal] of Object.entries(input.options)) {\n const ot = entityOptionTypes.find((t) => t.name === optName);\n if (!ot) {\n return Err(\n new CommerceValidationError(\n `Option type \"${optName}\" does not exist on this entity.`,\n ),\n );\n }\n const typeValues = await this.repo.findOptionValuesByTypeId(ot.id, ctx);\n const ov = typeValues.find((v) => v.value === optVal);\n if (!ov) {\n return Err(\n new CommerceValidationError(\n `Option value \"${optVal}\" does not exist for option type \"${optName}\".`,\n ),\n );\n }\n optionValueIds.push(ov.id);\n }\n\n const variant = await this.repo.createVariant(\n {\n entityId: input.entityId,\n status: \"active\",\n sortOrder: 0,\n metadata: {},\n ...(input.sku !== undefined ? { sku: input.sku } : {}),\n },\n ctx,\n );\n\n await this.repo.createVariantOptionValues(\n optionValueIds.map((optionValueId) => ({\n variantId: variant.id,\n optionValueId,\n })),\n ctx,\n );\n\n return Ok(variant);\n }\n\n async generateVariants(\n entityId: string,\n strategy: VariantGenerationStrategy,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Variant[]>> {\n assertPermission(actor, \"catalog:update\");\n\n const entity = await this.repo.findEntityById(entityId, ctx);\n if (!entity) return Err(new CommerceNotFoundError(\"Entity not found.\"));\n\n const entityOptionTypes = await this.repo.findOptionTypesByEntityId(\n entityId,\n ctx,\n );\n const sortedOptionTypes = entityOptionTypes.sort(\n (a, b) => a.sortOrder - b.sortOrder,\n );\n\n const optionValueGroups: string[][] = [];\n for (const optionType of sortedOptionTypes) {\n const values = await this.repo.findOptionValuesByTypeId(\n optionType.id,\n ctx,\n );\n const sortedValues = values.sort((a, b) => a.sortOrder - b.sortOrder);\n optionValueGroups.push(sortedValues.map((v) => v.id));\n }\n\n let combinations: string[][] = [];\n\n if (strategy.mode === \"all\") {\n combinations = cartesian(optionValueGroups);\n } else if (strategy.mode === \"manual\") {\n combinations = strategy.combinations;\n } else {\n const base = cartesian(optionValueGroups);\n const include = strategy.matrix.include;\n const exclude = strategy.matrix.exclude;\n combinations = base.filter((combo) => {\n const isExcluded = (exclude ?? []).some((pattern) =>\n pattern.every((val) => combo.includes(val)),\n );\n if (isExcluded) return false;\n if (!include || include.length === 0) return true;\n return include.some((pattern) =>\n pattern.every((val) => combo.includes(val)),\n );\n });\n }\n\n const created: Variant[] = [];\n for (const combo of combinations) {\n const variant = await this.repo.createVariant(\n {\n entityId,\n status: \"active\",\n sortOrder: 0,\n metadata: { generatedBy: strategy.mode },\n },\n ctx,\n );\n await this.repo.createVariantOptionValues(\n combo.map((optionValueId) => ({\n variantId: variant.id,\n optionValueId,\n })),\n ctx,\n );\n created.push(variant);\n }\n\n return Ok(created);\n }\n}\n",
|
|
88
|
+
"import type { Logger } from \"../kernel/hooks/types\";\n\nexport function createLogger(scope: string): Logger {\n return {\n info(message: string, data?: unknown) {\n // eslint-disable-next-line no-console\n console.info(`[${scope}] ${message}`, data ?? \"\");\n },\n warn(message: string, data?: unknown) {\n // eslint-disable-next-line no-console\n console.warn(`[${scope}] ${message}`, data ?? \"\");\n },\n error(message: string, data?: unknown) {\n // eslint-disable-next-line no-console\n console.error(`[${scope}] ${message}`, data ?? \"\");\n },\n };\n}\n",
|
|
89
|
+
"export interface Pagination {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n}\n\nexport function paginate<T>(items: T[], page: number, limit: number): { items: T[]; pagination: Pagination } {\n const safeLimit = Math.max(1, limit);\n const safePage = Math.max(1, page);\n const start = (safePage - 1) * safeLimit;\n const sliced = items.slice(start, start + safeLimit);\n return {\n items: sliced,\n pagination: {\n page: safePage,\n limit: safeLimit,\n total: items.length,\n totalPages: Math.max(1, Math.ceil(items.length / safeLimit)),\n },\n };\n}\n",
|
|
90
|
+
"import { eq, and, inArray, type SQL } from \"drizzle-orm\";\nimport type { TxContext } from \"../../../kernel/database/tx-context\";\nimport type {\n DrizzleDatabase,\n DbOrTx,\n} from \"../../../kernel/database/drizzle-db\";\nimport {\n sellableEntities,\n sellableAttributes,\n sellableCustomFields,\n categories,\n entityCategories,\n brands,\n entityBrands,\n optionTypes,\n optionValues,\n variants,\n variantOptionValues,\n} from \"../schema\";\n\n// Infer types from Drizzle schema\nexport type SellableEntity = typeof sellableEntities.$inferSelect;\nexport type SellableEntityInsert = typeof sellableEntities.$inferInsert;\nexport type SellableAttribute = typeof sellableAttributes.$inferSelect;\nexport type SellableAttributeInsert = typeof sellableAttributes.$inferInsert;\nexport type SellableCustomField = typeof sellableCustomFields.$inferSelect;\nexport type SellableCustomFieldInsert =\n typeof sellableCustomFields.$inferInsert;\nexport type Category = typeof categories.$inferSelect;\nexport type CategoryInsert = typeof categories.$inferInsert;\nexport type EntityCategory = typeof entityCategories.$inferSelect;\nexport type EntityCategoryInsert = typeof entityCategories.$inferInsert;\nexport type Brand = typeof brands.$inferSelect;\nexport type BrandInsert = typeof brands.$inferInsert;\nexport type EntityBrand = typeof entityBrands.$inferSelect;\nexport type EntityBrandInsert = typeof entityBrands.$inferInsert;\nexport type OptionType = typeof optionTypes.$inferSelect;\nexport type OptionTypeInsert = typeof optionTypes.$inferInsert;\nexport type OptionValue = typeof optionValues.$inferSelect;\nexport type OptionValueInsert = typeof optionValues.$inferInsert;\nexport type Variant = typeof variants.$inferSelect;\nexport type VariantInsert = typeof variants.$inferInsert;\nexport type VariantOptionValue = typeof variantOptionValues.$inferSelect;\nexport type VariantOptionValueInsert = typeof variantOptionValues.$inferInsert;\n\n/**\n * CatalogRepository provides type-safe database operations for catalog entities.\n *\n * This repository uses Drizzle ORM with PostgresJsDatabase for full type inference.\n * Transaction context is passed through TxContext when needed for transactional writes.\n *\n * All methods support an optional TxContext parameter for transaction participation.\n * When ctx is provided, operations run within that transaction; otherwise they use the main db.\n */\nexport class CatalogRepository {\n constructor(private readonly db: DrizzleDatabase) {}\n\n /**\n * Returns the appropriate database context - either a transaction or the main db.\n * Both DrizzleDatabase and DrizzleTx have the same query builder interface.\n */\n private getDb(ctx?: TxContext): DbOrTx {\n return (ctx?.tx as DbOrTx | undefined) ?? this.db;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Sellable Entities\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findEntityById(\n id: string,\n ctx?: TxContext,\n ): Promise<SellableEntity | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(sellableEntities)\n .where(eq(sellableEntities.id, id));\n return rows[0];\n }\n\n async findEntityBySlug(\n orgId: string,\n slug: string,\n ctx?: TxContext,\n ): Promise<SellableEntity | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(sellableEntities)\n .where(\n and(\n eq(sellableEntities.organizationId, orgId),\n eq(sellableEntities.slug, slug),\n ),\n );\n return rows[0];\n }\n\n async findEntities(\n orgId: string,\n filter?: {\n type?: string;\n status?: string;\n ids?: string[];\n },\n ctx?: TxContext,\n ): Promise<SellableEntity[]> {\n const db = this.getDb(ctx);\n const conditions: SQL[] = [eq(sellableEntities.organizationId, orgId)];\n\n if (filter?.type) {\n conditions.push(eq(sellableEntities.type, filter.type));\n }\n if (filter?.status) {\n conditions.push(\n eq(sellableEntities.status, filter.status as SellableEntity[\"status\"]),\n );\n }\n if (filter?.ids && filter.ids.length > 0) {\n conditions.push(inArray(sellableEntities.id, filter.ids));\n }\n\n return db\n .select()\n .from(sellableEntities)\n .where(conditions.length === 1 ? conditions[0] : and(...conditions));\n }\n\n async createEntity(\n data: SellableEntityInsert,\n ctx?: TxContext,\n ): Promise<SellableEntity> {\n const db = this.getDb(ctx);\n const rows = await db.insert(sellableEntities).values(data).returning();\n return rows[0]!;\n }\n\n async updateEntity(\n id: string,\n data: Partial<Omit<SellableEntityInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<SellableEntity | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(sellableEntities)\n .set({ ...data, updatedAt: new Date() })\n .where(eq(sellableEntities.id, id))\n .returning();\n return rows[0];\n }\n\n async deleteEntity(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(sellableEntities)\n .where(eq(sellableEntities.id, id))\n .returning();\n return result.length > 0;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Sellable Attributes\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findAttributesByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<SellableAttribute[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(sellableAttributes)\n .where(eq(sellableAttributes.entityId, entityId));\n }\n\n async findAttributeByLocale(\n entityId: string,\n locale: string,\n ctx?: TxContext,\n ): Promise<SellableAttribute | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(sellableAttributes)\n .where(\n and(\n eq(sellableAttributes.entityId, entityId),\n eq(sellableAttributes.locale, locale),\n ),\n );\n return rows[0];\n }\n\n async createAttribute(\n data: SellableAttributeInsert,\n ctx?: TxContext,\n ): Promise<SellableAttribute> {\n const db = this.getDb(ctx);\n const rows = await db.insert(sellableAttributes).values(data).returning();\n return rows[0]!;\n }\n\n async updateAttribute(\n id: string,\n data: Partial<Omit<SellableAttributeInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<SellableAttribute | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(sellableAttributes)\n .set(data)\n .where(eq(sellableAttributes.id, id))\n .returning();\n return rows[0];\n }\n\n async upsertAttribute(\n entityId: string,\n locale: string,\n data: Omit<SellableAttributeInsert, \"entityId\" | \"locale\">,\n ctx?: TxContext,\n ): Promise<SellableAttribute> {\n const existing = await this.findAttributeByLocale(entityId, locale, ctx);\n if (existing) {\n const updated = await this.updateAttribute(existing.id, data, ctx);\n return updated!;\n }\n return this.createAttribute({ ...data, entityId, locale }, ctx);\n }\n\n async deleteAttributesByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db\n .delete(sellableAttributes)\n .where(eq(sellableAttributes.entityId, entityId));\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Custom Fields\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findCustomFieldsByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<SellableCustomField[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(sellableCustomFields)\n .where(eq(sellableCustomFields.entityId, entityId));\n }\n\n async createCustomField(\n data: SellableCustomFieldInsert,\n ctx?: TxContext,\n ): Promise<SellableCustomField> {\n const db = this.getDb(ctx);\n const rows = await db.insert(sellableCustomFields).values(data).returning();\n return rows[0]!;\n }\n\n async deleteCustomFieldsByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db\n .delete(sellableCustomFields)\n .where(eq(sellableCustomFields.entityId, entityId));\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Categories\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findCategoryById(\n id: string,\n ctx?: TxContext,\n ): Promise<Category | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(categories)\n .where(eq(categories.id, id));\n return rows[0];\n }\n\n async findCategoryBySlug(\n orgId: string,\n slug: string,\n ctx?: TxContext,\n ): Promise<Category | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(categories)\n .where(\n and(\n eq(categories.organizationId, orgId),\n eq(categories.slug, slug),\n ),\n );\n return rows[0];\n }\n\n async findAllCategories(\n orgId: string,\n ctx?: TxContext,\n ): Promise<Category[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(categories)\n .where(eq(categories.organizationId, orgId));\n }\n\n async createCategory(\n data: CategoryInsert,\n ctx?: TxContext,\n ): Promise<Category> {\n const db = this.getDb(ctx);\n const rows = await db.insert(categories).values(data).returning();\n return rows[0]!;\n }\n\n async updateCategory(\n id: string,\n data: Partial<Omit<CategoryInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<Category | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(categories)\n .set(data)\n .where(eq(categories.id, id))\n .returning();\n return rows[0];\n }\n\n async deleteCategory(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(categories)\n .where(eq(categories.id, id))\n .returning();\n return result.length > 0;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Entity Categories (Join Table)\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findEntityCategories(\n entityId: string,\n ctx?: TxContext,\n ): Promise<EntityCategory[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(entityCategories)\n .where(eq(entityCategories.entityId, entityId));\n }\n\n async findEntitiesByCategory(\n categoryId: string,\n ctx?: TxContext,\n ): Promise<string[]> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(entityCategories)\n .where(eq(entityCategories.categoryId, categoryId));\n return rows.map((r) => r.entityId);\n }\n\n async addEntityToCategory(\n entityId: string,\n categoryId: string,\n sortOrder = 0,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db\n .insert(entityCategories)\n .values({ entityId, categoryId, sortOrder })\n .onConflictDoNothing();\n }\n\n async removeEntityFromCategory(\n entityId: string,\n categoryId: string,\n ctx?: TxContext,\n ): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(entityCategories)\n .where(\n and(\n eq(entityCategories.entityId, entityId),\n eq(entityCategories.categoryId, categoryId),\n ),\n )\n .returning();\n return result.length > 0;\n }\n\n async deleteEntityCategoriesByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db\n .delete(entityCategories)\n .where(eq(entityCategories.entityId, entityId));\n }\n\n async deleteEntityCategoriesByCategoryId(\n categoryId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db\n .delete(entityCategories)\n .where(eq(entityCategories.categoryId, categoryId));\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Brands\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findBrandById(id: string, ctx?: TxContext): Promise<Brand | undefined> {\n const db = this.getDb(ctx);\n const rows = await db.select().from(brands).where(eq(brands.id, id));\n return rows[0];\n }\n\n async findBrandBySlug(\n orgId: string,\n slug: string,\n ctx?: TxContext,\n ): Promise<Brand | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(brands)\n .where(\n and(\n eq(brands.organizationId, orgId),\n eq(brands.slug, slug),\n ),\n );\n return rows[0];\n }\n\n async findAllBrands(orgId: string, ctx?: TxContext): Promise<Brand[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(brands)\n .where(eq(brands.organizationId, orgId));\n }\n\n async createBrand(data: BrandInsert, ctx?: TxContext): Promise<Brand> {\n const db = this.getDb(ctx);\n const rows = await db.insert(brands).values(data).returning();\n return rows[0]!;\n }\n\n async updateBrand(\n id: string,\n data: Partial<Omit<BrandInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<Brand | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(brands)\n .set(data)\n .where(eq(brands.id, id))\n .returning();\n return rows[0];\n }\n\n async deleteBrand(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db.delete(brands).where(eq(brands.id, id)).returning();\n return result.length > 0;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Entity Brands (Join Table)\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findEntityBrands(\n entityId: string,\n ctx?: TxContext,\n ): Promise<EntityBrand[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(entityBrands)\n .where(eq(entityBrands.entityId, entityId));\n }\n\n async addEntityToBrand(\n entityId: string,\n brandId: string,\n sortOrder = 0,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db\n .insert(entityBrands)\n .values({ entityId, brandId, sortOrder })\n .onConflictDoNothing();\n }\n\n async removeEntityFromBrand(\n entityId: string,\n brandId: string,\n ctx?: TxContext,\n ): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(entityBrands)\n .where(\n and(\n eq(entityBrands.entityId, entityId),\n eq(entityBrands.brandId, brandId),\n ),\n )\n .returning();\n return result.length > 0;\n }\n\n async deleteEntityBrandsByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db.delete(entityBrands).where(eq(entityBrands.entityId, entityId));\n }\n\n async deleteEntityBrandsByBrandId(\n brandId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db.delete(entityBrands).where(eq(entityBrands.brandId, brandId));\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Option Types\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findOptionTypesByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<OptionType[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(optionTypes)\n .where(eq(optionTypes.entityId, entityId));\n }\n\n async findOptionTypeById(\n id: string,\n ctx?: TxContext,\n ): Promise<OptionType | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(optionTypes)\n .where(eq(optionTypes.id, id));\n return rows[0];\n }\n\n async createOptionType(\n data: OptionTypeInsert,\n ctx?: TxContext,\n ): Promise<OptionType> {\n const db = this.getDb(ctx);\n const rows = await db.insert(optionTypes).values(data).returning();\n return rows[0]!;\n }\n\n async deleteOptionTypesByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db.delete(optionTypes).where(eq(optionTypes.entityId, entityId));\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Option Values\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findOptionValuesByTypeId(\n optionTypeId: string,\n ctx?: TxContext,\n ): Promise<OptionValue[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(optionValues)\n .where(eq(optionValues.optionTypeId, optionTypeId));\n }\n\n async findOptionValueById(\n id: string,\n ctx?: TxContext,\n ): Promise<OptionValue | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(optionValues)\n .where(eq(optionValues.id, id));\n return rows[0];\n }\n\n async findOptionValuesByIds(\n ids: string[],\n ctx?: TxContext,\n ): Promise<OptionValue[]> {\n if (ids.length === 0) return [];\n const db = this.getDb(ctx);\n return db.select().from(optionValues).where(inArray(optionValues.id, ids));\n }\n\n async createOptionValue(\n data: OptionValueInsert,\n ctx?: TxContext,\n ): Promise<OptionValue> {\n const db = this.getDb(ctx);\n const rows = await db.insert(optionValues).values(data).returning();\n return rows[0]!;\n }\n\n async deleteOptionValuesByTypeId(\n optionTypeId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db\n .delete(optionValues)\n .where(eq(optionValues.optionTypeId, optionTypeId));\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Variants\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findVariantsByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<Variant[]> {\n const db = this.getDb(ctx);\n return db.select().from(variants).where(eq(variants.entityId, entityId));\n }\n\n async findVariantById(\n id: string,\n ctx?: TxContext,\n ): Promise<Variant | undefined> {\n const db = this.getDb(ctx);\n const rows = await db.select().from(variants).where(eq(variants.id, id));\n return rows[0];\n }\n\n async findVariantBySku(\n sku: string,\n ctx?: TxContext,\n ): Promise<Variant | undefined> {\n const db = this.getDb(ctx);\n const rows = await db.select().from(variants).where(eq(variants.sku, sku));\n return rows[0];\n }\n\n async findVariantByBarcode(\n barcode: string,\n ctx?: TxContext,\n ): Promise<Variant | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(variants)\n .where(eq(variants.barcode, barcode));\n return rows[0];\n }\n\n async createVariant(data: VariantInsert, ctx?: TxContext): Promise<Variant> {\n const db = this.getDb(ctx);\n const rows = await db.insert(variants).values(data).returning();\n return rows[0]!;\n }\n\n async updateVariant(\n id: string,\n data: Partial<Omit<VariantInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<Variant | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(variants)\n .set(data)\n .where(eq(variants.id, id))\n .returning();\n return rows[0];\n }\n\n async deleteVariantsByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db.delete(variants).where(eq(variants.entityId, entityId));\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Variant Option Values (Join Table)\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findVariantOptionValues(\n variantId: string,\n ctx?: TxContext,\n ): Promise<VariantOptionValue[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(variantOptionValues)\n .where(eq(variantOptionValues.variantId, variantId));\n }\n\n async createVariantOptionValues(\n data: VariantOptionValueInsert[],\n ctx?: TxContext,\n ): Promise<void> {\n if (data.length === 0) return;\n const db = this.getDb(ctx);\n await db.insert(variantOptionValues).values(data).onConflictDoNothing();\n }\n\n async deleteVariantOptionValuesByVariantId(\n variantId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db\n .delete(variantOptionValues)\n .where(eq(variantOptionValues.variantId, variantId));\n }\n\n async deleteVariantOptionValuesByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n // Get all variant IDs for this entity first\n const entityVariants = await this.findVariantsByEntityId(entityId, ctx);\n const variantIds = entityVariants.map((v) => v.id);\n if (variantIds.length > 0) {\n await db\n .delete(variantOptionValues)\n .where(inArray(variantOptionValues.variantId, variantIds));\n }\n }\n}\n",
|
|
91
|
+
"import { eq, and, inArray, isNull, sql } from \"drizzle-orm\";\nimport type { TxContext } from \"../../../kernel/database/tx-context\";\nimport type {\n DrizzleDatabase,\n DbOrTx,\n} from \"../../../kernel/database/drizzle-db\";\nimport { warehouses, inventoryLevels, inventoryMovements } from \"../schema\";\n\n// Infer types from Drizzle schema\nexport type Warehouse = typeof warehouses.$inferSelect;\nexport type WarehouseInsert = typeof warehouses.$inferInsert;\nexport type InventoryLevel = typeof inventoryLevels.$inferSelect;\nexport type InventoryLevelInsert = typeof inventoryLevels.$inferInsert;\nexport type InventoryMovement = typeof inventoryMovements.$inferSelect;\nexport type InventoryMovementInsert = typeof inventoryMovements.$inferInsert;\n\n/**\n * InventoryRepository provides type-safe database operations for inventory entities.\n *\n * This repository manages warehouses, inventory levels, and inventory movements.\n * All methods support an optional TxContext parameter for transaction participation.\n */\nexport class InventoryRepository {\n constructor(private readonly db: DrizzleDatabase) {}\n\n private getDb(ctx?: TxContext): DbOrTx {\n return (ctx?.tx as DbOrTx | undefined) ?? this.db;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Warehouses\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findWarehouseById(\n id: string,\n ctx?: TxContext,\n ): Promise<Warehouse | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(warehouses)\n .where(eq(warehouses.id, id));\n return rows[0];\n }\n\n async findWarehouseByCode(\n orgId: string,\n code: string,\n ctx?: TxContext,\n ): Promise<Warehouse | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(warehouses)\n .where(\n and(\n eq(warehouses.organizationId, orgId),\n eq(warehouses.code, code),\n ),\n );\n return rows[0];\n }\n\n async findAllWarehouses(\n orgId: string,\n ctx?: TxContext,\n ): Promise<Warehouse[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(warehouses)\n .where(eq(warehouses.organizationId, orgId));\n }\n\n async findActiveWarehouses(\n orgId: string,\n ctx?: TxContext,\n ): Promise<Warehouse[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(warehouses)\n .where(\n and(\n eq(warehouses.organizationId, orgId),\n eq(warehouses.isActive, true),\n ),\n );\n }\n\n async createWarehouse(\n data: WarehouseInsert,\n ctx?: TxContext,\n ): Promise<Warehouse> {\n const db = this.getDb(ctx);\n const rows = await db.insert(warehouses).values(data).returning();\n return rows[0]!;\n }\n\n async updateWarehouse(\n id: string,\n data: Partial<Omit<WarehouseInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<Warehouse | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(warehouses)\n .set(data)\n .where(eq(warehouses.id, id))\n .returning();\n return rows[0];\n }\n\n async deleteWarehouse(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(warehouses)\n .where(eq(warehouses.id, id))\n .returning();\n return result.length > 0;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Inventory Levels\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findAllLevels(ctx?: TxContext): Promise<InventoryLevel[]> {\n const db = this.getDb(ctx);\n return db.select().from(inventoryLevels);\n }\n\n async findLevelById(\n id: string,\n ctx?: TxContext,\n ): Promise<InventoryLevel | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(inventoryLevels)\n .where(eq(inventoryLevels.id, id));\n return rows[0];\n }\n\n async findLevelByKey(\n entityId: string,\n warehouseId: string,\n variantId?: string | null,\n ctx?: TxContext,\n ): Promise<InventoryLevel | undefined> {\n const db = this.getDb(ctx);\n const conditions = [\n eq(inventoryLevels.entityId, entityId),\n eq(inventoryLevels.warehouseId, warehouseId),\n ];\n\n // Only add variantId condition when it's a real string value — never pass null to eq()\n if (variantId != null) {\n conditions.push(eq(inventoryLevels.variantId, variantId));\n }\n\n const rows = await db\n .select()\n .from(inventoryLevels)\n .where(and(...conditions));\n\n // Post-filter for exact variantId match (handles SQL NULL correctly)\n return rows.find((r) => r.variantId === (variantId ?? null));\n }\n\n async findLevelsByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<InventoryLevel[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(inventoryLevels)\n .where(eq(inventoryLevels.entityId, entityId));\n }\n\n async findLevelsByEntityAndVariant(\n entityId: string,\n variantId?: string | null,\n ctx?: TxContext,\n ): Promise<InventoryLevel[]> {\n const db = this.getDb(ctx);\n const conditions = [eq(inventoryLevels.entityId, entityId)];\n\n // Only add variantId condition when it's a real string value — never pass null to eq()\n if (variantId != null) {\n conditions.push(eq(inventoryLevels.variantId, variantId));\n }\n\n const rows = await db\n .select()\n .from(inventoryLevels)\n .where(and(...conditions));\n\n // Post-filter for exact variantId match (handles SQL NULL correctly in JS)\n return rows.filter((r) =>\n variantId == null ? r.variantId === null : r.variantId === variantId,\n );\n }\n\n async findLevelsByWarehouseId(\n warehouseId: string,\n ctx?: TxContext,\n ): Promise<InventoryLevel[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(inventoryLevels)\n .where(eq(inventoryLevels.warehouseId, warehouseId));\n }\n\n async createLevel(\n data: InventoryLevelInsert,\n ctx?: TxContext,\n ): Promise<InventoryLevel> {\n const db = this.getDb(ctx);\n const rows = await db.insert(inventoryLevels).values(data).returning();\n return rows[0]!;\n }\n\n async updateLevel(\n id: string,\n data: Partial<Omit<InventoryLevelInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<InventoryLevel | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(inventoryLevels)\n .set({ ...data, updatedAt: new Date() })\n .where(eq(inventoryLevels.id, id))\n .returning();\n return rows[0];\n }\n\n async upsertLevel(\n entityId: string,\n warehouseId: string,\n variantId: string | undefined,\n data: Omit<\n InventoryLevelInsert,\n \"id\" | \"entityId\" | \"warehouseId\" | \"variantId\"\n >,\n ctx?: TxContext,\n ): Promise<InventoryLevel> {\n const existing = await this.findLevelByKey(\n entityId,\n warehouseId,\n variantId,\n ctx,\n );\n if (existing) {\n const updated = await this.updateLevel(existing.id, data, ctx);\n return updated!;\n }\n return this.createLevel(\n {\n ...data,\n entityId,\n warehouseId,\n ...(variantId !== undefined ? { variantId } : {}),\n },\n ctx,\n );\n }\n\n async deleteLevel(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(inventoryLevels)\n .where(eq(inventoryLevels.id, id))\n .returning();\n return result.length > 0;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Inventory Movements\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findMovementById(\n id: string,\n ctx?: TxContext,\n ): Promise<InventoryMovement | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(inventoryMovements)\n .where(eq(inventoryMovements.id, id));\n return rows[0];\n }\n\n async findMovementsByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<InventoryMovement[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(inventoryMovements)\n .where(eq(inventoryMovements.entityId, entityId));\n }\n\n async findMovementsByReference(\n referenceType: string,\n referenceId: string,\n ctx?: TxContext,\n ): Promise<InventoryMovement[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(inventoryMovements)\n .where(\n and(\n eq(inventoryMovements.referenceType, referenceType),\n eq(inventoryMovements.referenceId, referenceId),\n ),\n );\n }\n\n async createMovement(\n data: InventoryMovementInsert,\n ctx?: TxContext,\n ): Promise<InventoryMovement> {\n const db = this.getDb(ctx);\n const rows = await db.insert(inventoryMovements).values(data).returning();\n return rows[0]!;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Concurrency-Safe Operations (SELECT FOR UPDATE)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Issues SELECT ... FOR UPDATE on the inventory_levels row matching\n * the given entity, variant, and warehouse within the provided transaction.\n *\n * MUST be called inside an active transaction (ctx.tx must be set).\n * Calling outside a transaction provides no locking guarantee.\n *\n * Uses isNull() for null variantId instead of eq() to generate correct\n * SQL (IS NULL instead of = NULL).\n */\n async findLevelForUpdate(\n entityId: string,\n variantId: string | null,\n warehouseId: string,\n ctx: TxContext,\n ): Promise<InventoryLevel | undefined> {\n const db = this.getDb(ctx);\n\n const conditions = [\n eq(inventoryLevels.entityId, entityId),\n eq(inventoryLevels.warehouseId, warehouseId),\n variantId != null\n ? eq(inventoryLevels.variantId, variantId)\n : isNull(inventoryLevels.variantId),\n ];\n\n // Use raw SQL for FOR UPDATE since Drizzle's .for() may not be available\n // on all query builder paths. This is the most portable approach.\n const rows = await db\n .select()\n .from(inventoryLevels)\n .where(and(...conditions))\n .for(\"update\");\n\n return rows[0];\n }\n\n /**\n * Performs a read-modify-write under a row-level lock.\n * This is the ONLY correct method for modifying quantityReserved\n * in a concurrent environment. Must be called inside a transaction.\n *\n * The lock is held for the duration of the enclosing transaction,\n * which is typically just the checkout reservation — microsecond-level.\n */\n async reserveWithLock(\n entityId: string,\n variantId: string | null,\n warehouseId: string,\n quantity: number,\n ctx: TxContext,\n ): Promise<\n { ok: true; level: InventoryLevel } | { ok: false; reason: string }\n > {\n const level = await this.findLevelForUpdate(\n entityId,\n variantId,\n warehouseId,\n ctx,\n );\n\n if (!level) {\n return {\n ok: false,\n reason: \"No inventory record found for this entity.\",\n };\n }\n\n const available = level.quantityOnHand - level.quantityReserved;\n if (available < quantity) {\n return {\n ok: false,\n reason: `Insufficient stock. Available: ${available}, requested: ${quantity}.`,\n };\n }\n\n const updated = await this.getDb(ctx)\n .update(inventoryLevels)\n .set({\n quantityReserved: level.quantityReserved + quantity,\n updatedAt: new Date(),\n version: level.version + 1,\n })\n .where(eq(inventoryLevels.id, level.id))\n .returning();\n\n return { ok: true, level: updated[0]! };\n }\n\n /**\n * Performs a release under a row-level lock, mirroring reserveWithLock.\n * Used by compensation chains to undo a reservation.\n */\n async releaseWithLock(\n entityId: string,\n variantId: string | null,\n warehouseId: string,\n quantity: number,\n ctx: TxContext,\n ): Promise<\n { ok: true; level: InventoryLevel } | { ok: false; reason: string }\n > {\n const level = await this.findLevelForUpdate(\n entityId,\n variantId,\n warehouseId,\n ctx,\n );\n\n if (!level) {\n return {\n ok: false,\n reason: \"No inventory record found for this entity.\",\n };\n }\n\n const updated = await this.getDb(ctx)\n .update(inventoryLevels)\n .set({\n quantityReserved: Math.max(0, level.quantityReserved - quantity),\n updatedAt: new Date(),\n version: level.version + 1,\n })\n .where(eq(inventoryLevels.id, level.id))\n .returning();\n\n return { ok: true, level: updated[0]! };\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Aggregate Queries\n // ─────────────────────────────────────────────────────────────────────────────\n\n async getAvailableQuantity(\n entityId: string,\n variantId?: string | null,\n ctx?: TxContext,\n ): Promise<number> {\n const levels = await this.findLevelsByEntityAndVariant(\n entityId,\n variantId,\n ctx,\n );\n return levels.reduce(\n (sum, level) => sum + (level.quantityOnHand - level.quantityReserved),\n 0,\n );\n }\n\n async getAvailableQuantities(\n entityIds: string[],\n ctx?: TxContext,\n ): Promise<Record<string, number>> {\n if (entityIds.length === 0) return {};\n\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(inventoryLevels)\n .where(inArray(inventoryLevels.entityId, entityIds));\n\n const result: Record<string, number> = {};\n for (const id of entityIds) {\n result[id] = 0;\n }\n\n for (const row of rows) {\n const available = row.quantityOnHand - row.quantityReserved;\n result[row.entityId] = (result[row.entityId] ?? 0) + available;\n }\n\n return result;\n }\n}\n",
|
|
92
|
+
"import { eq, and, lt } from \"drizzle-orm\";\nimport type { TxContext } from \"../../../kernel/database/tx-context\";\nimport type {\n DrizzleDatabase,\n DbOrTx,\n} from \"../../../kernel/database/drizzle-db\";\nimport { carts, cartLineItems } from \"../schema\";\n\n// Infer types from Drizzle schema\nexport type Cart = typeof carts.$inferSelect;\nexport type CartInsert = typeof carts.$inferInsert;\nexport type CartLineItem = typeof cartLineItems.$inferSelect;\nexport type CartLineItemInsert = typeof cartLineItems.$inferInsert;\n\n/**\n * CartRepository provides type-safe database operations for shopping carts.\n *\n * This repository manages carts and cart line items.\n * All methods support an optional TxContext parameter for transaction participation.\n */\nexport class CartRepository {\n constructor(private readonly db: DrizzleDatabase) {}\n\n private getDb(ctx?: TxContext): DbOrTx {\n return (ctx?.tx as DbOrTx | undefined) ?? this.db;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Carts\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findById(orgId: string, id: string, ctx?: TxContext): Promise<Cart | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(carts)\n .where(and(eq(carts.organizationId, orgId), eq(carts.id, id)));\n return rows[0];\n }\n\n async findByCustomerId(\n orgId: string,\n customerId: string,\n ctx?: TxContext,\n ): Promise<Cart | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(carts)\n .where(and(eq(carts.organizationId, orgId), eq(carts.customerId, customerId), eq(carts.status, \"active\")));\n return rows[0];\n }\n\n async findActiveByCustomerId(\n orgId: string,\n customerId: string,\n ctx?: TxContext,\n ): Promise<Cart | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(carts)\n .where(and(eq(carts.organizationId, orgId), eq(carts.customerId, customerId), eq(carts.status, \"active\")));\n return rows[0];\n }\n\n async findExpiredCarts(ctx?: TxContext): Promise<Cart[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(carts)\n .where(and(eq(carts.status, \"active\"), lt(carts.expiresAt, new Date())));\n }\n\n async create(data: CartInsert, ctx?: TxContext): Promise<Cart> {\n const db = this.getDb(ctx);\n const rows = await db.insert(carts).values(data).returning();\n return rows[0]!;\n }\n\n async update(\n id: string,\n data: Partial<Omit<CartInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<Cart | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(carts)\n .set({ ...data, updatedAt: new Date() })\n .where(eq(carts.id, id))\n .returning();\n return rows[0];\n }\n\n async updateStatus(\n id: string,\n status: Cart[\"status\"],\n ctx?: TxContext,\n ): Promise<Cart | undefined> {\n return this.update(id, { status }, ctx);\n }\n\n /**\n * Atomically transitions a cart from \"active\" to \"checking_out\".\n * Returns the updated cart if the transition succeeded, or undefined if\n * the cart was not in \"active\" status (e.g., a concurrent checkout already\n * claimed it). This prevents TOCTOU race conditions on double-checkout.\n */\n async transitionToCheckingOut(\n id: string,\n ctx?: TxContext,\n ): Promise<Cart | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(carts)\n .set({ status: \"checking_out\", updatedAt: new Date() })\n .where(and(eq(carts.id, id), eq(carts.status, \"active\")))\n .returning();\n return rows[0];\n }\n\n async delete(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db.delete(carts).where(eq(carts.id, id)).returning();\n return result.length > 0;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Cart Line Items\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findLineItemById(\n id: string,\n ctx?: TxContext,\n ): Promise<CartLineItem | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(cartLineItems)\n .where(eq(cartLineItems.id, id));\n return rows[0];\n }\n\n async findLineItemsByCartId(\n cartId: string,\n ctx?: TxContext,\n ): Promise<CartLineItem[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(cartLineItems)\n .where(eq(cartLineItems.cartId, cartId));\n }\n\n async findLineItemByEntity(\n cartId: string,\n entityId: string,\n variantId?: string,\n ctx?: TxContext,\n ): Promise<CartLineItem | undefined> {\n const db = this.getDb(ctx);\n const conditions = [\n eq(cartLineItems.cartId, cartId),\n eq(cartLineItems.entityId, entityId),\n ];\n\n if (variantId !== undefined) {\n conditions.push(eq(cartLineItems.variantId, variantId));\n }\n\n const rows = await db\n .select()\n .from(cartLineItems)\n .where(and(...conditions));\n\n // Filter for exact variantId match\n return rows.find((r) => r.variantId === (variantId ?? null));\n }\n\n async createLineItem(\n data: CartLineItemInsert,\n ctx?: TxContext,\n ): Promise<CartLineItem> {\n const db = this.getDb(ctx);\n const rows = await db.insert(cartLineItems).values(data).returning();\n return rows[0]!;\n }\n\n async updateLineItem(\n id: string,\n data: Partial<Omit<CartLineItemInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<CartLineItem | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(cartLineItems)\n .set(data)\n .where(eq(cartLineItems.id, id))\n .returning();\n return rows[0];\n }\n\n async deleteLineItem(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(cartLineItems)\n .where(eq(cartLineItems.id, id))\n .returning();\n return result.length > 0;\n }\n\n async deleteLineItemsByCartId(\n cartId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db.delete(cartLineItems).where(eq(cartLineItems.cartId, cartId));\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Cart with Line Items (Aggregate)\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findWithLineItems(\n orgId: string,\n id: string,\n ctx?: TxContext,\n ): Promise<{ cart: Cart; lineItems: CartLineItem[] } | undefined> {\n const cart = await this.findById(orgId, id, ctx);\n if (!cart) return undefined;\n const lineItems = await this.findLineItemsByCartId(id, ctx);\n return { cart, lineItems };\n }\n}\n",
|
|
93
|
+
"import { eq, and, desc, sql } from \"drizzle-orm\";\nimport type { TxContext } from \"../../../kernel/database/tx-context\";\nimport type {\n DrizzleDatabase,\n DbOrTx,\n} from \"../../../kernel/database/drizzle-db\";\nimport { orders, orderLineItems, orderStatusHistory } from \"../schema\";\n\n// Infer types from Drizzle schema\nexport type Order = typeof orders.$inferSelect;\nexport type OrderInsert = typeof orders.$inferInsert;\nexport type OrderLineItem = typeof orderLineItems.$inferSelect;\nexport type OrderLineItemInsert = typeof orderLineItems.$inferInsert;\nexport type OrderStatusHistory = typeof orderStatusHistory.$inferSelect;\nexport type OrderStatusHistoryInsert = typeof orderStatusHistory.$inferInsert;\n\n/**\n * OrdersRepository provides type-safe database operations for orders.\n *\n * This repository manages orders, order line items, and order status history.\n * All methods support an optional TxContext parameter for transaction participation.\n */\nexport class OrdersRepository {\n constructor(private readonly db: DrizzleDatabase) {}\n\n private getDb(ctx?: TxContext): DbOrTx {\n return (ctx?.tx as DbOrTx | undefined) ?? this.db;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Orders\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findById(orgId: string, id: string, ctx?: TxContext): Promise<Order | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(orders)\n .where(and(eq(orders.organizationId, orgId), eq(orders.id, id)));\n return rows[0];\n }\n\n async findByOrderNumber(\n orgId: string,\n orderNumber: string,\n ctx?: TxContext,\n ): Promise<Order | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(orders)\n .where(and(eq(orders.organizationId, orgId), eq(orders.orderNumber, orderNumber)));\n return rows[0];\n }\n\n async findByCustomerId(\n orgId: string,\n customerId: string,\n ctx?: TxContext,\n ): Promise<Order[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(orders)\n .where(and(eq(orders.organizationId, orgId), eq(orders.customerId, customerId)))\n .orderBy(desc(orders.placedAt));\n }\n\n async findByStatus(orgId: string, status: string, ctx?: TxContext): Promise<Order[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(orders)\n .where(and(eq(orders.organizationId, orgId), eq(orders.status, status)))\n .orderBy(desc(orders.placedAt));\n }\n\n async findAll(\n orgId: string,\n options?: { limit?: number; offset?: number },\n ctx?: TxContext,\n ): Promise<Order[]> {\n const db = this.getDb(ctx);\n let query = db\n .select()\n .from(orders)\n .where(eq(orders.organizationId, orgId))\n .orderBy(desc(orders.placedAt))\n .$dynamic();\n\n if (options?.limit !== undefined) {\n query = query.limit(options.limit);\n }\n if (options?.offset !== undefined) {\n query = query.offset(options.offset);\n }\n return query;\n }\n\n async create(data: OrderInsert, ctx?: TxContext): Promise<Order> {\n const db = this.getDb(ctx);\n const rows = await db.insert(orders).values(data).returning();\n return rows[0]!;\n }\n\n async update(\n id: string,\n data: Partial<Omit<OrderInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<Order | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(orders)\n .set(data)\n .where(eq(orders.id, id))\n .returning();\n return rows[0];\n }\n\n async updateStatus(\n id: string,\n currentStatus: string,\n newStatus: string,\n ctx?: TxContext,\n ): Promise<Order | undefined> {\n const db = this.getDb(ctx);\n const data: Partial<OrderInsert> = { status: newStatus };\n if (newStatus === \"fulfilled\") {\n data.fulfilledAt = new Date();\n } else if (newStatus === \"cancelled\") {\n data.cancelledAt = new Date();\n }\n // Atomic guard: only update if current status matches expected\n const rows = await db\n .update(orders)\n .set(data)\n .where(and(eq(orders.id, id), eq(orders.status, currentStatus)))\n .returning();\n return rows[0];\n }\n\n async delete(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db.delete(orders).where(eq(orders.id, id)).returning();\n return result.length > 0;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Order Line Items\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findAllLineItems(ctx?: TxContext): Promise<OrderLineItem[]> {\n const db = this.getDb(ctx);\n return db.select().from(orderLineItems);\n }\n\n async findLineItemById(\n id: string,\n ctx?: TxContext,\n ): Promise<OrderLineItem | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(orderLineItems)\n .where(eq(orderLineItems.id, id));\n return rows[0];\n }\n\n async findLineItemsByOrderId(\n orderId: string,\n ctx?: TxContext,\n ): Promise<OrderLineItem[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(orderLineItems)\n .where(eq(orderLineItems.orderId, orderId));\n }\n\n async createLineItem(\n data: OrderLineItemInsert,\n ctx?: TxContext,\n ): Promise<OrderLineItem> {\n const db = this.getDb(ctx);\n const rows = await db.insert(orderLineItems).values(data).returning();\n return rows[0]!;\n }\n\n async createLineItems(\n data: OrderLineItemInsert[],\n ctx?: TxContext,\n ): Promise<OrderLineItem[]> {\n if (data.length === 0) return [];\n const db = this.getDb(ctx);\n return db.insert(orderLineItems).values(data).returning();\n }\n\n async updateLineItem(\n id: string,\n data: Partial<Omit<OrderLineItemInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<OrderLineItem | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(orderLineItems)\n .set(data)\n .where(eq(orderLineItems.id, id))\n .returning();\n return rows[0];\n }\n\n async deleteLineItem(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(orderLineItems)\n .where(eq(orderLineItems.id, id))\n .returning();\n return result.length > 0;\n }\n\n async deleteLineItemsByOrderId(\n orderId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db.delete(orderLineItems).where(eq(orderLineItems.orderId, orderId));\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Order Status History\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findStatusHistoryByOrderId(\n orderId: string,\n ctx?: TxContext,\n ): Promise<OrderStatusHistory[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(orderStatusHistory)\n .where(eq(orderStatusHistory.orderId, orderId))\n .orderBy(desc(orderStatusHistory.changedAt));\n }\n\n async createStatusHistory(\n data: OrderStatusHistoryInsert,\n ctx?: TxContext,\n ): Promise<OrderStatusHistory> {\n const db = this.getDb(ctx);\n const rows = await db.insert(orderStatusHistory).values(data).returning();\n return rows[0]!;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Order with Line Items (Aggregate)\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findWithLineItems(\n orgId: string,\n id: string,\n ctx?: TxContext,\n ): Promise<{ order: Order; lineItems: OrderLineItem[] } | undefined> {\n const order = await this.findById(orgId, id, ctx);\n if (!order) return undefined;\n const lineItems = await this.findLineItemsByOrderId(id, ctx);\n return { order, lineItems };\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Order Number Generation\n // ─────────────────────────────────────────────────────────────────────────────\n\n async getNextOrderNumber(ctx?: TxContext): Promise<string> {\n const year = new Date().getFullYear();\n const db = this.getDb(ctx);\n\n // Count orders from this year to generate sequential number\n const result = await db\n .select({ count: sql<number>`count(*)::int` })\n .from(orders)\n .where(sql`EXTRACT(YEAR FROM ${orders.placedAt}) = ${year}`);\n\n const count = result[0]?.count ?? 0;\n const sequence = count + 1;\n return `ORD-${year}-${String(sequence).padStart(6, \"0\")}`;\n }\n}\n",
|
|
94
|
+
"import { eq, and } from \"drizzle-orm\";\nimport type { TxContext } from \"../../../kernel/database/tx-context\";\nimport type {\n DrizzleDatabase,\n DbOrTx,\n} from \"../../../kernel/database/drizzle-db\";\nimport {\n customers,\n customerAddresses,\n customerGroups,\n customerGroupMembers,\n} from \"../schema\";\n\n// Infer types from Drizzle schema\nexport type Customer = typeof customers.$inferSelect;\nexport type CustomerInsert = typeof customers.$inferInsert;\nexport type CustomerAddress = typeof customerAddresses.$inferSelect;\nexport type CustomerAddressInsert = typeof customerAddresses.$inferInsert;\nexport type CustomerGroup = typeof customerGroups.$inferSelect;\nexport type CustomerGroupInsert = typeof customerGroups.$inferInsert;\nexport type CustomerGroupMember = typeof customerGroupMembers.$inferSelect;\nexport type CustomerGroupMemberInsert =\n typeof customerGroupMembers.$inferInsert;\n\n/**\n * CustomersRepository provides type-safe database operations for customers.\n *\n * This repository manages customers, addresses, groups, and group memberships.\n * All methods support an optional TxContext parameter for transaction participation.\n */\nexport class CustomersRepository {\n constructor(private readonly db: DrizzleDatabase) {}\n\n private getDb(ctx?: TxContext): DbOrTx {\n return (ctx?.tx as DbOrTx | undefined) ?? this.db;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Customers\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findById(orgId: string, id: string, ctx?: TxContext): Promise<Customer | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(customers)\n .where(and(eq(customers.organizationId, orgId), eq(customers.id, id)));\n return rows[0];\n }\n\n async findByUserId(\n orgId: string,\n userId: string,\n ctx?: TxContext,\n ): Promise<Customer | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(customers)\n .where(and(eq(customers.organizationId, orgId), eq(customers.userId, userId)));\n return rows[0];\n }\n\n async findByEmail(\n orgId: string,\n email: string,\n ctx?: TxContext,\n ): Promise<Customer | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(customers)\n .where(and(eq(customers.organizationId, orgId), eq(customers.email, email)));\n return rows[0];\n }\n\n async findByPosPin(\n orgId: string,\n hashedPin: string,\n ctx?: TxContext,\n ): Promise<Customer | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(customers)\n .where(and(eq(customers.organizationId, orgId), eq(customers.posOperatorPin, hashedPin)));\n return rows[0];\n }\n\n async findAll(orgId: string, ctx?: TxContext): Promise<Customer[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(customers)\n .where(eq(customers.organizationId, orgId));\n }\n\n async create(data: CustomerInsert, ctx?: TxContext): Promise<Customer> {\n const db = this.getDb(ctx);\n const rows = await db.insert(customers).values(data).returning();\n return rows[0]!;\n }\n\n async update(\n id: string,\n data: Partial<Omit<CustomerInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<Customer | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(customers)\n .set({ ...data, updatedAt: new Date() })\n .where(eq(customers.id, id))\n .returning();\n return rows[0];\n }\n\n async delete(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(customers)\n .where(eq(customers.id, id))\n .returning();\n return result.length > 0;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Customer Addresses\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findAddressById(\n id: string,\n ctx?: TxContext,\n ): Promise<CustomerAddress | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(customerAddresses)\n .where(eq(customerAddresses.id, id));\n return rows[0];\n }\n\n async findAddressesByCustomerId(\n customerId: string,\n ctx?: TxContext,\n ): Promise<CustomerAddress[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(customerAddresses)\n .where(eq(customerAddresses.customerId, customerId));\n }\n\n async findDefaultAddress(\n customerId: string,\n type: \"shipping\" | \"billing\",\n ctx?: TxContext,\n ): Promise<CustomerAddress | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(customerAddresses)\n .where(\n and(\n eq(customerAddresses.customerId, customerId),\n eq(customerAddresses.type, type),\n eq(customerAddresses.isDefault, true),\n ),\n );\n return rows[0];\n }\n\n async createAddress(\n data: CustomerAddressInsert,\n ctx?: TxContext,\n ): Promise<CustomerAddress> {\n const db = this.getDb(ctx);\n const rows = await db.insert(customerAddresses).values(data).returning();\n return rows[0]!;\n }\n\n async updateAddress(\n id: string,\n data: Partial<Omit<CustomerAddressInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<CustomerAddress | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(customerAddresses)\n .set(data)\n .where(eq(customerAddresses.id, id))\n .returning();\n return rows[0];\n }\n\n async deleteAddress(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(customerAddresses)\n .where(eq(customerAddresses.id, id))\n .returning();\n return result.length > 0;\n }\n\n async deleteAddressesByCustomerId(\n customerId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db\n .delete(customerAddresses)\n .where(eq(customerAddresses.customerId, customerId));\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Customer Groups\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findGroupById(\n orgId: string,\n id: string,\n ctx?: TxContext,\n ): Promise<CustomerGroup | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(customerGroups)\n .where(and(eq(customerGroups.organizationId, orgId), eq(customerGroups.id, id)));\n return rows[0];\n }\n\n async findGroupByName(\n orgId: string,\n name: string,\n ctx?: TxContext,\n ): Promise<CustomerGroup | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(customerGroups)\n .where(and(eq(customerGroups.organizationId, orgId), eq(customerGroups.name, name)));\n return rows[0];\n }\n\n async findAllGroups(orgId: string, ctx?: TxContext): Promise<CustomerGroup[]> {\n const db = this.getDb(ctx);\n return db.select().from(customerGroups).where(eq(customerGroups.organizationId, orgId));\n }\n\n async createGroup(\n data: CustomerGroupInsert,\n ctx?: TxContext,\n ): Promise<CustomerGroup> {\n const db = this.getDb(ctx);\n const rows = await db.insert(customerGroups).values(data).returning();\n return rows[0]!;\n }\n\n async updateGroup(\n id: string,\n data: Partial<Omit<CustomerGroupInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<CustomerGroup | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(customerGroups)\n .set(data)\n .where(eq(customerGroups.id, id))\n .returning();\n return rows[0];\n }\n\n async deleteGroup(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(customerGroups)\n .where(eq(customerGroups.id, id))\n .returning();\n return result.length > 0;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Customer Group Members\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findGroupsByCustomerId(\n customerId: string,\n ctx?: TxContext,\n ): Promise<string[]> {\n const db = this.getDb(ctx);\n const rows = await db\n .select({ groupId: customerGroupMembers.groupId })\n .from(customerGroupMembers)\n .where(eq(customerGroupMembers.customerId, customerId));\n return rows.map((r) => r.groupId);\n }\n\n async addToGroup(\n customerId: string,\n groupId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db\n .insert(customerGroupMembers)\n .values({ customerId, groupId })\n .onConflictDoNothing();\n }\n\n async removeFromGroup(\n customerId: string,\n groupId: string,\n ctx?: TxContext,\n ): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(customerGroupMembers)\n .where(\n and(\n eq(customerGroupMembers.customerId, customerId),\n eq(customerGroupMembers.groupId, groupId),\n ),\n )\n .returning();\n return result.length > 0;\n }\n}\n",
|
|
95
|
+
"import { eq, and, lte, gte, or, isNull } from \"drizzle-orm\";\nimport type { TxContext } from \"../../../kernel/database/tx-context\";\nimport type {\n DrizzleDatabase,\n DbOrTx,\n} from \"../../../kernel/database/drizzle-db\";\nimport { prices, priceModifiers } from \"../schema\";\n\n// Infer types from Drizzle schema\nexport type Price = typeof prices.$inferSelect;\nexport type PriceInsert = typeof prices.$inferInsert;\nexport type PriceModifier = typeof priceModifiers.$inferSelect;\nexport type PriceModifierInsert = typeof priceModifiers.$inferInsert;\n\n/**\n * PricingRepository provides type-safe database operations for pricing.\n *\n * This repository manages prices and price modifiers.\n * All methods support an optional TxContext parameter for transaction participation.\n */\nexport class PricingRepository {\n constructor(private readonly db: DrizzleDatabase) {}\n\n private getDb(ctx?: TxContext): DbOrTx {\n return (ctx?.tx as DbOrTx | undefined) ?? this.db;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Prices\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findPriceById(orgId: string, id: string, ctx?: TxContext): Promise<Price | undefined> {\n const db = this.getDb(ctx);\n const rows = await db.select().from(prices).where(\n and(eq(prices.organizationId, orgId), eq(prices.id, id)),\n );\n return rows[0];\n }\n\n async findPricesByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<Price[]> {\n const db = this.getDb(ctx);\n return db.select().from(prices).where(eq(prices.entityId, entityId));\n }\n\n async findPricesByEntityAndVariant(\n entityId: string,\n variantId: string | null,\n ctx?: TxContext,\n ): Promise<Price[]> {\n const db = this.getDb(ctx);\n\n if (variantId === null) {\n return db\n .select()\n .from(prices)\n .where(and(eq(prices.entityId, entityId), isNull(prices.variantId)));\n }\n\n return db\n .select()\n .from(prices)\n .where(\n and(eq(prices.entityId, entityId), eq(prices.variantId, variantId)),\n );\n }\n\n async findActivePrices(\n entityId: string,\n currency: string,\n variantId?: string,\n customerGroupId?: string,\n quantity?: number,\n ctx?: TxContext,\n ): Promise<Price[]> {\n const db = this.getDb(ctx);\n const now = new Date();\n\n const rows = await db\n .select()\n .from(prices)\n .where(\n and(\n eq(prices.entityId, entityId),\n eq(prices.currency, currency),\n or(isNull(prices.validFrom), lte(prices.validFrom, now)),\n or(isNull(prices.validUntil), gte(prices.validUntil, now)),\n ),\n );\n\n // Filter by variantId\n let filtered = rows.filter((p) => {\n if (variantId === undefined) return p.variantId === null;\n return p.variantId === variantId || p.variantId === null;\n });\n\n // Filter by customerGroupId\n if (customerGroupId) {\n filtered = filtered.filter(\n (p) =>\n p.customerGroupId === null || p.customerGroupId === customerGroupId,\n );\n } else {\n filtered = filtered.filter((p) => p.customerGroupId === null);\n }\n\n // Filter by quantity\n if (quantity !== undefined) {\n filtered = filtered.filter((p) => {\n const minOk = p.minQuantity === null || quantity >= p.minQuantity;\n const maxOk = p.maxQuantity === null || quantity <= p.maxQuantity;\n return minOk && maxOk;\n });\n }\n\n return filtered;\n }\n\n async createPrice(data: PriceInsert, ctx?: TxContext): Promise<Price> {\n const db = this.getDb(ctx);\n const rows = await db.insert(prices).values(data).returning();\n return rows[0]!;\n }\n\n async updatePrice(\n id: string,\n data: Partial<Omit<PriceInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<Price | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(prices)\n .set({ ...data, updatedAt: new Date() })\n .where(eq(prices.id, id))\n .returning();\n return rows[0];\n }\n\n async deletePrice(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db.delete(prices).where(eq(prices.id, id)).returning();\n return result.length > 0;\n }\n\n async deletePricesByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db.delete(prices).where(eq(prices.entityId, entityId));\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Price Modifiers\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findModifierById(\n orgId: string,\n id: string,\n ctx?: TxContext,\n ): Promise<PriceModifier | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(priceModifiers)\n .where(and(eq(priceModifiers.organizationId, orgId), eq(priceModifiers.id, id)));\n return rows[0];\n }\n\n async findModifiersByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<PriceModifier[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(priceModifiers)\n .where(eq(priceModifiers.entityId, entityId));\n }\n\n async findActiveModifiers(\n entityId: string,\n variantId?: string,\n customerGroupId?: string,\n currency?: string,\n quantity?: number,\n ctx?: TxContext,\n ): Promise<PriceModifier[]> {\n const db = this.getDb(ctx);\n const now = new Date();\n\n const rows = await db\n .select()\n .from(priceModifiers)\n .where(\n and(\n or(\n isNull(priceModifiers.entityId),\n eq(priceModifiers.entityId, entityId),\n ),\n or(\n isNull(priceModifiers.validFrom),\n lte(priceModifiers.validFrom, now),\n ),\n or(\n isNull(priceModifiers.validUntil),\n gte(priceModifiers.validUntil, now),\n ),\n ),\n );\n\n // Filter by variantId\n let filtered = rows.filter((m) => {\n if (m.variantId === null) return true;\n return m.variantId === variantId;\n });\n\n // Filter by customerGroupId\n if (customerGroupId) {\n filtered = filtered.filter(\n (m) =>\n m.customerGroupId === null || m.customerGroupId === customerGroupId,\n );\n } else {\n filtered = filtered.filter((m) => m.customerGroupId === null);\n }\n\n // Filter by currency\n if (currency) {\n filtered = filtered.filter(\n (m) => m.currency === null || m.currency === currency,\n );\n }\n\n // Filter by quantity\n if (quantity !== undefined) {\n filtered = filtered.filter((m) => {\n const minOk = m.minQuantity === null || quantity >= m.minQuantity;\n const maxOk = m.maxQuantity === null || quantity <= m.maxQuantity;\n return minOk && maxOk;\n });\n }\n\n // Sort by priority (lower number = higher priority)\n return filtered.sort((a, b) => a.priority - b.priority);\n }\n\n async createModifier(\n data: PriceModifierInsert,\n ctx?: TxContext,\n ): Promise<PriceModifier> {\n const db = this.getDb(ctx);\n const rows = await db.insert(priceModifiers).values(data).returning();\n return rows[0]!;\n }\n\n async updateModifier(\n id: string,\n data: Partial<Omit<PriceModifierInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<PriceModifier | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(priceModifiers)\n .set({ ...data, updatedAt: new Date() })\n .where(eq(priceModifiers.id, id))\n .returning();\n return rows[0];\n }\n\n async deleteModifier(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(priceModifiers)\n .where(eq(priceModifiers.id, id))\n .returning();\n return result.length > 0;\n }\n\n async deleteModifiersByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db\n .delete(priceModifiers)\n .where(eq(priceModifiers.entityId, entityId));\n }\n}\n",
|
|
96
|
+
"import { eq, and, lte, gte, or, isNull, desc, sql } from \"drizzle-orm\";\nimport type { TxContext } from \"../../../kernel/database/tx-context\";\nimport type {\n DrizzleDatabase,\n DbOrTx,\n} from \"../../../kernel/database/drizzle-db\";\nimport { promotions, promotionUsages } from \"../schema\";\n\n// Infer types from Drizzle schema\nexport type Promotion = typeof promotions.$inferSelect;\nexport type PromotionInsert = typeof promotions.$inferInsert;\nexport type PromotionUsage = typeof promotionUsages.$inferSelect;\nexport type PromotionUsageInsert = typeof promotionUsages.$inferInsert;\n\n/**\n * PromotionsRepository provides type-safe database operations for promotions.\n *\n * This repository manages promotions and their usage tracking.\n * All methods support an optional TxContext parameter for transaction participation.\n */\nexport class PromotionsRepository {\n constructor(private readonly db: DrizzleDatabase) {}\n\n private getDb(ctx?: TxContext): DbOrTx {\n return (ctx?.tx as DbOrTx | undefined) ?? this.db;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Promotions\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findById(orgId: string, id: string, ctx?: TxContext): Promise<Promotion | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(promotions)\n .where(and(eq(promotions.organizationId, orgId), eq(promotions.id, id)));\n return rows[0];\n }\n\n async findByCode(\n orgId: string,\n code: string,\n ctx?: TxContext,\n ): Promise<Promotion | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(promotions)\n .where(\n and(\n eq(promotions.organizationId, orgId),\n eq(promotions.code, code),\n ),\n );\n return rows[0];\n }\n\n async findAll(orgId: string, ctx?: TxContext): Promise<Promotion[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(promotions)\n .where(eq(promotions.organizationId, orgId))\n .orderBy(desc(promotions.priority));\n }\n\n async findActive(orgId: string, ctx?: TxContext): Promise<Promotion[]> {\n const db = this.getDb(ctx);\n const now = new Date();\n\n return db\n .select()\n .from(promotions)\n .where(\n and(\n eq(promotions.organizationId, orgId),\n eq(promotions.isActive, true),\n or(isNull(promotions.validFrom), lte(promotions.validFrom, now)),\n or(isNull(promotions.validUntil), gte(promotions.validUntil, now)),\n ),\n )\n .orderBy(desc(promotions.priority));\n }\n\n async findAutomatic(orgId: string, ctx?: TxContext): Promise<Promotion[]> {\n const db = this.getDb(ctx);\n const now = new Date();\n\n return db\n .select()\n .from(promotions)\n .where(\n and(\n eq(promotions.organizationId, orgId),\n eq(promotions.isActive, true),\n eq(promotions.isAutomatic, true),\n or(isNull(promotions.validFrom), lte(promotions.validFrom, now)),\n or(isNull(promotions.validUntil), gte(promotions.validUntil, now)),\n ),\n )\n .orderBy(desc(promotions.priority));\n }\n\n async create(data: PromotionInsert, ctx?: TxContext): Promise<Promotion> {\n const db = this.getDb(ctx);\n const rows = await db.insert(promotions).values(data).returning();\n return rows[0]!;\n }\n\n async update(\n id: string,\n data: Partial<Omit<PromotionInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<Promotion | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(promotions)\n .set({ ...data, updatedAt: new Date() })\n .where(eq(promotions.id, id))\n .returning();\n return rows[0];\n }\n\n async delete(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(promotions)\n .where(eq(promotions.id, id))\n .returning();\n return result.length > 0;\n }\n\n async activate(id: string, ctx?: TxContext): Promise<Promotion | undefined> {\n return this.update(id, { isActive: true }, ctx);\n }\n\n async deactivate(\n id: string,\n ctx?: TxContext,\n ): Promise<Promotion | undefined> {\n return this.update(id, { isActive: false }, ctx);\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Promotion Usages\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findUsageById(\n id: string,\n ctx?: TxContext,\n ): Promise<PromotionUsage | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(promotionUsages)\n .where(eq(promotionUsages.id, id));\n return rows[0];\n }\n\n async findUsagesByPromotionId(\n promotionId: string,\n ctx?: TxContext,\n ): Promise<PromotionUsage[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(promotionUsages)\n .where(eq(promotionUsages.promotionId, promotionId));\n }\n\n async findUsagesByCustomerId(\n customerId: string,\n ctx?: TxContext,\n ): Promise<PromotionUsage[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(promotionUsages)\n .where(eq(promotionUsages.customerId, customerId));\n }\n\n async createUsage(\n data: PromotionUsageInsert,\n ctx?: TxContext,\n ): Promise<PromotionUsage> {\n const db = this.getDb(ctx);\n\n // Atomic guard: use INSERT ... SELECT WHERE count < limit to prevent\n // race conditions between concurrent checkouts using the same coupon.\n // A plain count-then-insert has a TOCTOU gap; this single statement\n // ensures the insert only succeeds if the limit has not been reached.\n const promo = await db\n .select({ usageLimitTotal: promotions.usageLimitTotal })\n .from(promotions)\n .where(eq(promotions.id, data.promotionId));\n\n const limit = promo[0]?.usageLimitTotal;\n\n if (limit != null) {\n // Atomic guard: lock the promotion row and check usage count in the\n // same statement sequence. This prevents two concurrent checkouts\n // from both passing the count check (TOCTOU race).\n //\n // SELECT ... FOR UPDATE acquires a row-level lock that serializes\n // concurrent callers. If the caller is already inside a transaction\n // (ctx.tx), the lock is held until that transaction commits.\n await db.execute(\n sql`SELECT id FROM promotions WHERE id = ${data.promotionId} FOR UPDATE`,\n );\n\n const currentCount = await this.countUsages(data.promotionId, ctx);\n if (currentCount >= limit) {\n throw new Error(`Promotion usage limit reached (${currentCount}/${limit})`);\n }\n\n const rows = await db.insert(promotionUsages).values(data).returning();\n return rows[0]!;\n }\n\n const rows = await db.insert(promotionUsages).values(data).returning();\n return rows[0]!;\n }\n\n async countUsages(promotionId: string, ctx?: TxContext): Promise<number> {\n const db = this.getDb(ctx);\n const result = await db\n .select({ count: sql<number>`count(*)::int` })\n .from(promotionUsages)\n .where(eq(promotionUsages.promotionId, promotionId));\n return result[0]?.count ?? 0;\n }\n\n async countUsagesByCustomer(\n promotionId: string,\n customerId: string,\n ctx?: TxContext,\n ): Promise<number> {\n const db = this.getDb(ctx);\n const result = await db\n .select({ count: sql<number>`count(*)::int` })\n .from(promotionUsages)\n .where(\n and(\n eq(promotionUsages.promotionId, promotionId),\n eq(promotionUsages.customerId, customerId),\n ),\n );\n return result[0]?.count ?? 0;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Validation Helpers\n // ─────────────────────────────────────────────────────────────────────────────\n\n async isUsageLimitReached(\n orgId: string,\n promotionId: string,\n ctx?: TxContext,\n ): Promise<boolean> {\n const promotion = await this.findById(orgId, promotionId, ctx);\n if (!promotion || promotion.usageLimitTotal === null) {\n return false;\n }\n const count = await this.countUsages(promotionId, ctx);\n return count >= promotion.usageLimitTotal;\n }\n\n async isCustomerUsageLimitReached(\n orgId: string,\n promotionId: string,\n customerId: string,\n ctx?: TxContext,\n ): Promise<boolean> {\n const promotion = await this.findById(orgId, promotionId, ctx);\n if (!promotion || promotion.usageLimitPerCustomer === null) {\n return false;\n }\n const count = await this.countUsagesByCustomer(\n promotionId,\n customerId,\n ctx,\n );\n return count >= promotion.usageLimitPerCustomer;\n }\n\n async isPromotionValid(\n orgId: string,\n promotionId: string,\n customerId?: string,\n ctx?: TxContext,\n ): Promise<{ valid: boolean; reason?: string }> {\n const promotion = await this.findById(orgId, promotionId, ctx);\n\n if (!promotion) {\n return { valid: false, reason: \"Promotion not found\" };\n }\n\n if (!promotion.isActive) {\n return { valid: false, reason: \"Promotion is not active\" };\n }\n\n const now = new Date();\n if (promotion.validFrom && promotion.validFrom > now) {\n return { valid: false, reason: \"Promotion has not started yet\" };\n }\n\n if (promotion.validUntil && promotion.validUntil < now) {\n return { valid: false, reason: \"Promotion has expired\" };\n }\n\n if (await this.isUsageLimitReached(orgId, promotionId, ctx)) {\n return { valid: false, reason: \"Promotion usage limit reached\" };\n }\n\n if (\n customerId &&\n (await this.isCustomerUsageLimitReached(orgId, promotionId, customerId, ctx))\n ) {\n return { valid: false, reason: \"Customer usage limit reached\" };\n }\n\n return { valid: true };\n }\n}\n",
|
|
97
|
+
"import { eq, desc, and, sql } from \"drizzle-orm\";\nimport type { TxContext } from \"../../../kernel/database/tx-context\";\nimport type {\n DrizzleDatabase,\n DbOrTx,\n} from \"../../../kernel/database/drizzle-db\";\nimport {\n fulfillmentRecords,\n fulfillmentLineItems,\n fulfillmentEvents,\n} from \"../schema\";\n\n// Infer types from Drizzle schema\nexport type FulfillmentRecord = typeof fulfillmentRecords.$inferSelect;\nexport type FulfillmentRecordInsert = typeof fulfillmentRecords.$inferInsert;\nexport type FulfillmentLineItem = typeof fulfillmentLineItems.$inferSelect;\nexport type FulfillmentLineItemInsert =\n typeof fulfillmentLineItems.$inferInsert;\nexport type FulfillmentEvent = typeof fulfillmentEvents.$inferSelect;\nexport type FulfillmentEventInsert = typeof fulfillmentEvents.$inferInsert;\n\n/**\n * FulfillmentRepository provides type-safe database operations for fulfillments.\n *\n * This repository manages fulfillment records, line item associations, and events.\n * Supports physical shipments, digital deliveries, and access grants.\n * All methods support an optional TxContext parameter for transaction participation.\n */\nexport class FulfillmentRepository {\n constructor(private readonly db: DrizzleDatabase) {}\n\n private getDb(ctx?: TxContext): DbOrTx {\n return (ctx?.tx as DbOrTx | undefined) ?? this.db;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Fulfillment Records\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findById(\n id: string,\n ctx?: TxContext,\n ): Promise<FulfillmentRecord | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(fulfillmentRecords)\n .where(eq(fulfillmentRecords.id, id));\n return rows[0];\n }\n\n async findByOrderId(\n orderId: string,\n ctx?: TxContext,\n ): Promise<FulfillmentRecord[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(fulfillmentRecords)\n .where(eq(fulfillmentRecords.orderId, orderId))\n .orderBy(desc(fulfillmentRecords.createdAt));\n }\n\n async findByCustomerId(\n customerId: string,\n ctx?: TxContext,\n ): Promise<FulfillmentRecord[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(fulfillmentRecords)\n .where(eq(fulfillmentRecords.customerId, customerId))\n .orderBy(desc(fulfillmentRecords.createdAt));\n }\n\n async findByStatus(\n status: string,\n ctx?: TxContext,\n ): Promise<FulfillmentRecord[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(fulfillmentRecords)\n .where(eq(fulfillmentRecords.status, status))\n .orderBy(desc(fulfillmentRecords.createdAt));\n }\n\n async findByType(\n type: string,\n ctx?: TxContext,\n ): Promise<FulfillmentRecord[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(fulfillmentRecords)\n .where(eq(fulfillmentRecords.type, type))\n .orderBy(desc(fulfillmentRecords.createdAt));\n }\n\n async findByOrderIdAndStatus(\n orderId: string,\n status: string,\n ctx?: TxContext,\n ): Promise<FulfillmentRecord[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(fulfillmentRecords)\n .where(\n and(\n eq(fulfillmentRecords.orderId, orderId),\n eq(fulfillmentRecords.status, status),\n ),\n )\n .orderBy(desc(fulfillmentRecords.createdAt));\n }\n\n async findActiveAccessGrants(\n customerId: string,\n ctx?: TxContext,\n ): Promise<FulfillmentRecord[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(fulfillmentRecords)\n .where(\n and(\n eq(fulfillmentRecords.customerId, customerId),\n eq(fulfillmentRecords.type, \"access_grant\"),\n eq(fulfillmentRecords.isActive, true),\n ),\n )\n .orderBy(desc(fulfillmentRecords.grantedAt));\n }\n\n async findAll(\n options?: { limit?: number; offset?: number },\n ctx?: TxContext,\n ): Promise<FulfillmentRecord[]> {\n const db = this.getDb(ctx);\n let query = db\n .select()\n .from(fulfillmentRecords)\n .orderBy(desc(fulfillmentRecords.createdAt))\n .$dynamic();\n\n if (options?.limit !== undefined) {\n query = query.limit(options.limit);\n }\n if (options?.offset !== undefined) {\n query = query.offset(options.offset);\n }\n return query;\n }\n\n async create(\n data: FulfillmentRecordInsert,\n ctx?: TxContext,\n ): Promise<FulfillmentRecord> {\n const db = this.getDb(ctx);\n const rows = await db.insert(fulfillmentRecords).values(data).returning();\n return rows[0]!;\n }\n\n async update(\n id: string,\n data: Partial<Omit<FulfillmentRecordInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<FulfillmentRecord | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(fulfillmentRecords)\n .set({ ...data, updatedAt: new Date() })\n .where(eq(fulfillmentRecords.id, id))\n .returning();\n return rows[0];\n }\n\n async updateStatus(\n id: string,\n status: string,\n ctx?: TxContext,\n ): Promise<FulfillmentRecord | undefined> {\n const data: Partial<FulfillmentRecordInsert> = { status };\n\n // Set timestamps based on status\n if (status === \"shipped\") {\n data.shippedAt = new Date();\n } else if (status === \"delivered\") {\n data.deliveredAt = new Date();\n }\n\n return this.update(id, data, ctx);\n }\n\n async delete(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(fulfillmentRecords)\n .where(eq(fulfillmentRecords.id, id))\n .returning();\n return result.length > 0;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Digital Delivery Operations\n // ─────────────────────────────────────────────────────────────────────────────\n\n async incrementDownloadCount(\n id: string,\n ctx?: TxContext,\n ): Promise<FulfillmentRecord | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(fulfillmentRecords)\n .set({\n downloadCount: sql`${fulfillmentRecords.downloadCount} + 1`,\n updatedAt: new Date(),\n })\n .where(eq(fulfillmentRecords.id, id))\n .returning();\n return rows[0];\n }\n\n async isDownloadAllowed(id: string, ctx?: TxContext): Promise<boolean> {\n const fulfillment = await this.findById(id, ctx);\n if (!fulfillment || fulfillment.type !== \"digital\") return false;\n\n // Check expiration\n if (\n fulfillment.downloadExpiresAt &&\n new Date() > fulfillment.downloadExpiresAt\n ) {\n return false;\n }\n\n // Check download limit\n if (\n fulfillment.maxDownloads !== null &&\n fulfillment.downloadCount >= fulfillment.maxDownloads\n ) {\n return false;\n }\n\n return true;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Access Grant Operations\n // ─────────────────────────────────────────────────────────────────────────────\n\n async deactivateAccessGrant(\n id: string,\n ctx?: TxContext,\n ): Promise<FulfillmentRecord | undefined> {\n return this.update(id, { isActive: false }, ctx);\n }\n\n async activateAccessGrant(\n id: string,\n ctx?: TxContext,\n ): Promise<FulfillmentRecord | undefined> {\n return this.update(id, { isActive: true, grantedAt: new Date() }, ctx);\n }\n\n async isAccessGrantActive(id: string, ctx?: TxContext): Promise<boolean> {\n const fulfillment = await this.findById(id, ctx);\n if (!fulfillment || fulfillment.type !== \"access_grant\") return false;\n\n if (!fulfillment.isActive) return false;\n\n // Check expiration\n if (fulfillment.expiresAt && new Date() > fulfillment.expiresAt) {\n return false;\n }\n\n return true;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Fulfillment Line Items\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findLineItemsByFulfillmentId(\n fulfillmentId: string,\n ctx?: TxContext,\n ): Promise<FulfillmentLineItem[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(fulfillmentLineItems)\n .where(eq(fulfillmentLineItems.fulfillmentId, fulfillmentId));\n }\n\n async findLineItemsByOrderLineItemId(\n orderLineItemId: string,\n ctx?: TxContext,\n ): Promise<FulfillmentLineItem[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(fulfillmentLineItems)\n .where(eq(fulfillmentLineItems.orderLineItemId, orderLineItemId));\n }\n\n async createLineItem(\n data: FulfillmentLineItemInsert,\n ctx?: TxContext,\n ): Promise<FulfillmentLineItem> {\n const db = this.getDb(ctx);\n const rows = await db.insert(fulfillmentLineItems).values(data).returning();\n return rows[0]!;\n }\n\n async createLineItems(\n data: FulfillmentLineItemInsert[],\n ctx?: TxContext,\n ): Promise<FulfillmentLineItem[]> {\n if (data.length === 0) return [];\n const db = this.getDb(ctx);\n return db.insert(fulfillmentLineItems).values(data).returning();\n }\n\n async deleteLineItemsByFulfillmentId(\n fulfillmentId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db\n .delete(fulfillmentLineItems)\n .where(eq(fulfillmentLineItems.fulfillmentId, fulfillmentId));\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Fulfillment Events\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findEventsByFulfillmentId(\n fulfillmentId: string,\n ctx?: TxContext,\n ): Promise<FulfillmentEvent[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(fulfillmentEvents)\n .where(eq(fulfillmentEvents.fulfillmentId, fulfillmentId))\n .orderBy(desc(fulfillmentEvents.occurredAt));\n }\n\n async createEvent(\n data: FulfillmentEventInsert,\n ctx?: TxContext,\n ): Promise<FulfillmentEvent> {\n const db = this.getDb(ctx);\n const rows = await db.insert(fulfillmentEvents).values(data).returning();\n return rows[0]!;\n }\n\n async recordStatusChange(\n fulfillmentId: string,\n fromStatus: string,\n toStatus: string,\n actorId?: string,\n description?: string,\n ctx?: TxContext,\n ): Promise<FulfillmentEvent> {\n return this.createEvent(\n {\n fulfillmentId,\n eventType: \"status_change\",\n fromStatus,\n toStatus,\n actorId,\n description,\n },\n ctx,\n );\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Aggregate Operations\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findWithLineItems(\n id: string,\n ctx?: TxContext,\n ): Promise<\n | { fulfillment: FulfillmentRecord; lineItems: FulfillmentLineItem[] }\n | undefined\n > {\n const fulfillment = await this.findById(id, ctx);\n if (!fulfillment) return undefined;\n const lineItems = await this.findLineItemsByFulfillmentId(id, ctx);\n return { fulfillment, lineItems };\n }\n\n async findWithEvents(\n id: string,\n ctx?: TxContext,\n ): Promise<\n { fulfillment: FulfillmentRecord; events: FulfillmentEvent[] } | undefined\n > {\n const fulfillment = await this.findById(id, ctx);\n if (!fulfillment) return undefined;\n const events = await this.findEventsByFulfillmentId(id, ctx);\n return { fulfillment, events };\n }\n\n /**\n * Get fulfilled quantity for an order line item.\n * Sums all fulfillment line items linked to the order line item.\n */\n async getFulfilledQuantity(\n orderLineItemId: string,\n ctx?: TxContext,\n ): Promise<number> {\n const db = this.getDb(ctx);\n const result = await db\n .select({\n total: sql<number>`COALESCE(SUM(${fulfillmentLineItems.quantity}), 0)::int`,\n })\n .from(fulfillmentLineItems)\n .where(eq(fulfillmentLineItems.orderLineItemId, orderLineItemId));\n return result[0]?.total ?? 0;\n }\n}\n",
|
|
98
|
+
"import { eq, and, lte, isNull, or, desc, sql } from \"drizzle-orm\";\nimport type { TxContext } from \"../../../kernel/database/tx-context\";\nimport type {\n DrizzleDatabase,\n DbOrTx,\n} from \"../../../kernel/database/drizzle-db\";\nimport { webhookEndpoints, webhookDeliveries } from \"../schema\";\n\n// Infer types from Drizzle schema\nexport type WebhookEndpoint = typeof webhookEndpoints.$inferSelect;\nexport type WebhookEndpointInsert = typeof webhookEndpoints.$inferInsert;\nexport type WebhookDelivery = typeof webhookDeliveries.$inferSelect;\nexport type WebhookDeliveryInsert = typeof webhookDeliveries.$inferInsert;\n\n/**\n * WebhooksRepository provides type-safe database operations for webhooks.\n *\n * This repository manages webhook endpoints and their delivery tracking.\n * All methods support an optional TxContext parameter for transaction participation.\n */\nexport class WebhooksRepository {\n constructor(private readonly db: DrizzleDatabase) {}\n\n private getDb(ctx?: TxContext): DbOrTx {\n return (ctx?.tx as DbOrTx | undefined) ?? this.db;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Webhook Endpoints\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findEndpointById(\n id: string,\n ctx?: TxContext,\n ): Promise<WebhookEndpoint | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(webhookEndpoints)\n .where(eq(webhookEndpoints.id, id));\n return rows[0];\n }\n\n async findAllEndpoints(ctx?: TxContext): Promise<WebhookEndpoint[]> {\n const db = this.getDb(ctx);\n return db.select().from(webhookEndpoints);\n }\n\n async findActiveEndpoints(ctx?: TxContext): Promise<WebhookEndpoint[]> {\n const db = this.getDb(ctx);\n return db\n .select()\n .from(webhookEndpoints)\n .where(eq(webhookEndpoints.isActive, true));\n }\n\n async findEndpointsForEvent(\n eventName: string,\n ctx?: TxContext,\n ): Promise<WebhookEndpoint[]> {\n const active = await this.findActiveEndpoints(ctx);\n // Filter endpoints that subscribe to this event\n return active.filter((endpoint) => {\n const events = endpoint.events as string[];\n return events.includes(eventName) || events.includes(\"*\");\n });\n }\n\n async createEndpoint(\n data: WebhookEndpointInsert,\n ctx?: TxContext,\n ): Promise<WebhookEndpoint> {\n const db = this.getDb(ctx);\n const rows = await db.insert(webhookEndpoints).values(data).returning();\n return rows[0]!;\n }\n\n async updateEndpoint(\n id: string,\n data: Partial<Omit<WebhookEndpointInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<WebhookEndpoint | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(webhookEndpoints)\n .set(data)\n .where(eq(webhookEndpoints.id, id))\n .returning();\n return rows[0];\n }\n\n async deleteEndpoint(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(webhookEndpoints)\n .where(eq(webhookEndpoints.id, id))\n .returning();\n return result.length > 0;\n }\n\n async activateEndpoint(\n id: string,\n ctx?: TxContext,\n ): Promise<WebhookEndpoint | undefined> {\n return this.updateEndpoint(id, { isActive: true }, ctx);\n }\n\n async deactivateEndpoint(\n id: string,\n ctx?: TxContext,\n ): Promise<WebhookEndpoint | undefined> {\n return this.updateEndpoint(id, { isActive: false }, ctx);\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Webhook Deliveries\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findDeliveryById(\n id: string,\n ctx?: TxContext,\n ): Promise<WebhookDelivery | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(webhookDeliveries)\n .where(eq(webhookDeliveries.id, id));\n return rows[0];\n }\n\n async findDeliveriesByEndpointId(\n endpointId: string,\n options?: { limit?: number },\n ctx?: TxContext,\n ): Promise<WebhookDelivery[]> {\n const db = this.getDb(ctx);\n let query = db\n .select()\n .from(webhookDeliveries)\n .where(eq(webhookDeliveries.endpointId, endpointId))\n .orderBy(desc(webhookDeliveries.createdAt))\n .$dynamic();\n\n if (options?.limit !== undefined) {\n query = query.limit(options.limit);\n }\n\n return query;\n }\n\n async findPendingDeliveries(ctx?: TxContext): Promise<WebhookDelivery[]> {\n const db = this.getDb(ctx);\n const now = new Date();\n\n return db\n .select()\n .from(webhookDeliveries)\n .where(\n and(\n isNull(webhookDeliveries.deliveredAt),\n isNull(webhookDeliveries.failedAt),\n or(\n isNull(webhookDeliveries.nextRetryAt),\n lte(webhookDeliveries.nextRetryAt, now),\n ),\n ),\n )\n .orderBy(webhookDeliveries.createdAt);\n }\n\n async findFailedDeliveries(\n endpointId?: string,\n ctx?: TxContext,\n ): Promise<WebhookDelivery[]> {\n const db = this.getDb(ctx);\n\n if (endpointId) {\n return db\n .select()\n .from(webhookDeliveries)\n .where(\n and(\n eq(webhookDeliveries.endpointId, endpointId),\n sql`${webhookDeliveries.failedAt} IS NOT NULL`,\n ),\n )\n .orderBy(desc(webhookDeliveries.failedAt));\n }\n\n return db\n .select()\n .from(webhookDeliveries)\n .where(sql`${webhookDeliveries.failedAt} IS NOT NULL`)\n .orderBy(desc(webhookDeliveries.failedAt));\n }\n\n async createDelivery(\n data: WebhookDeliveryInsert,\n ctx?: TxContext,\n ): Promise<WebhookDelivery> {\n const db = this.getDb(ctx);\n const rows = await db.insert(webhookDeliveries).values(data).returning();\n return rows[0]!;\n }\n\n async updateDelivery(\n id: string,\n data: Partial<Omit<WebhookDeliveryInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<WebhookDelivery | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(webhookDeliveries)\n .set(data)\n .where(eq(webhookDeliveries.id, id))\n .returning();\n return rows[0];\n }\n\n async markDelivered(\n id: string,\n statusCode: number,\n ctx?: TxContext,\n ): Promise<WebhookDelivery | undefined> {\n return this.updateDelivery(\n id,\n {\n statusCode,\n deliveredAt: new Date(),\n nextRetryAt: null,\n },\n ctx,\n );\n }\n\n async markFailed(\n id: string,\n statusCode: number | null,\n nextRetryAt?: Date,\n ctx?: TxContext,\n ): Promise<WebhookDelivery | undefined> {\n const delivery = await this.findDeliveryById(id, ctx);\n if (!delivery) return undefined;\n\n const data: Partial<WebhookDeliveryInsert> = {\n statusCode: statusCode ?? undefined,\n attemptCount: delivery.attemptCount + 1,\n };\n\n if (nextRetryAt) {\n data.nextRetryAt = nextRetryAt;\n } else {\n data.failedAt = new Date();\n data.nextRetryAt = null;\n }\n\n return this.updateDelivery(id, data, ctx);\n }\n\n async deleteDelivery(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(webhookDeliveries)\n .where(eq(webhookDeliveries.id, id))\n .returning();\n return result.length > 0;\n }\n\n async deleteDeliveriesByEndpointId(\n endpointId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db\n .delete(webhookDeliveries)\n .where(eq(webhookDeliveries.endpointId, endpointId));\n }\n}\n",
|
|
99
|
+
"import { eq, and, inArray } from \"drizzle-orm\";\nimport type { TxContext } from \"../../../kernel/database/tx-context\";\nimport type {\n DrizzleDatabase,\n DbOrTx,\n} from \"../../../kernel/database/drizzle-db\";\nimport { mediaAssets, entityMedia } from \"../schema\";\n\n// Infer types from Drizzle schema\nexport type MediaAsset = typeof mediaAssets.$inferSelect;\nexport type MediaAssetInsert = typeof mediaAssets.$inferInsert;\nexport type EntityMedia = typeof entityMedia.$inferSelect;\nexport type EntityMediaInsert = typeof entityMedia.$inferInsert;\n\n/**\n * MediaRepository provides type-safe database operations for media assets.\n *\n * This repository manages media assets and their associations with entities.\n * All methods support an optional TxContext parameter for transaction participation.\n */\nexport class MediaRepository {\n constructor(private readonly db: DrizzleDatabase) {}\n\n private getDb(ctx?: TxContext): DbOrTx {\n return (ctx?.tx as DbOrTx | undefined) ?? this.db;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Media Assets\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findAssetById(\n id: string,\n ctx?: TxContext,\n orgId?: string,\n ): Promise<MediaAsset | undefined> {\n const db = this.getDb(ctx);\n const conditions = [eq(mediaAssets.id, id)];\n if (orgId) {\n conditions.push(eq(mediaAssets.organizationId, orgId));\n }\n const rows = await db\n .select()\n .from(mediaAssets)\n .where(and(...conditions));\n return rows[0];\n }\n\n async findAssetByStorageKey(\n storageKey: string,\n ctx?: TxContext,\n ): Promise<MediaAsset | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .select()\n .from(mediaAssets)\n .where(eq(mediaAssets.storageKey, storageKey));\n return rows[0];\n }\n\n async findAssetsByIds(ids: string[], ctx?: TxContext): Promise<MediaAsset[]> {\n if (ids.length === 0) return [];\n const db = this.getDb(ctx);\n return db.select().from(mediaAssets).where(inArray(mediaAssets.id, ids));\n }\n\n async createAsset(\n data: MediaAssetInsert,\n ctx?: TxContext,\n ): Promise<MediaAsset> {\n const db = this.getDb(ctx);\n const rows = await db.insert(mediaAssets).values(data).returning();\n return rows[0]!;\n }\n\n async updateAsset(\n id: string,\n data: Partial<Omit<MediaAssetInsert, \"id\">>,\n ctx?: TxContext,\n ): Promise<MediaAsset | undefined> {\n const db = this.getDb(ctx);\n const rows = await db\n .update(mediaAssets)\n .set(data)\n .where(eq(mediaAssets.id, id))\n .returning();\n return rows[0];\n }\n\n async deleteAsset(id: string, ctx?: TxContext): Promise<boolean> {\n const db = this.getDb(ctx);\n const result = await db\n .delete(mediaAssets)\n .where(eq(mediaAssets.id, id))\n .returning();\n return result.length > 0;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Entity Media (Associations)\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findEntityMedia(\n entityId: string,\n variantId?: string,\n ctx?: TxContext,\n ): Promise<EntityMedia[]> {\n const db = this.getDb(ctx);\n\n if (variantId === undefined) {\n // Find media for entity only (not variant-specific)\n const rows = await db\n .select()\n .from(entityMedia)\n .where(eq(entityMedia.entityId, entityId));\n return rows.filter((r) => r.variantId === null);\n }\n\n return db\n .select()\n .from(entityMedia)\n .where(\n and(\n eq(entityMedia.entityId, entityId),\n eq(entityMedia.variantId, variantId),\n ),\n );\n }\n\n async findEntityMediaByRole(\n entityId: string,\n role: EntityMedia[\"role\"],\n variantId?: string,\n ctx?: TxContext,\n ): Promise<EntityMedia[]> {\n const db = this.getDb(ctx);\n const conditions = [\n eq(entityMedia.entityId, entityId),\n eq(entityMedia.role, role),\n ];\n\n if (variantId !== undefined) {\n conditions.push(eq(entityMedia.variantId, variantId));\n }\n\n const rows = await db\n .select()\n .from(entityMedia)\n .where(and(...conditions));\n\n if (variantId === undefined) {\n return rows.filter((r) => r.variantId === null);\n }\n return rows;\n }\n\n async findPrimaryMedia(\n entityId: string,\n variantId?: string,\n ctx?: TxContext,\n ): Promise<EntityMedia | undefined> {\n const media = await this.findEntityMediaByRole(\n entityId,\n \"primary\",\n variantId,\n ctx,\n );\n return media[0];\n }\n\n async createEntityMedia(\n data: EntityMediaInsert,\n ctx?: TxContext,\n ): Promise<EntityMedia> {\n const db = this.getDb(ctx);\n const rows = await db.insert(entityMedia).values(data).returning();\n return rows[0]!;\n }\n\n async createEntityMediaBatch(\n data: EntityMediaInsert[],\n ctx?: TxContext,\n ): Promise<EntityMedia[]> {\n if (data.length === 0) return [];\n const db = this.getDb(ctx);\n return db.insert(entityMedia).values(data).returning();\n }\n\n async updateEntityMediaSortOrder(\n entityId: string,\n mediaAssetId: string,\n sortOrder: number,\n variantId?: string,\n ctx?: TxContext,\n ): Promise<EntityMedia | undefined> {\n const db = this.getDb(ctx);\n const conditions = [\n eq(entityMedia.entityId, entityId),\n eq(entityMedia.mediaAssetId, mediaAssetId),\n ];\n\n if (variantId !== undefined) {\n conditions.push(eq(entityMedia.variantId, variantId));\n }\n\n const rows = await db\n .update(entityMedia)\n .set({ sortOrder })\n .where(and(...conditions))\n .returning();\n\n if (variantId === undefined) {\n return rows.find((r) => r.variantId === null);\n }\n return rows[0];\n }\n\n async removeEntityMedia(\n entityId: string,\n mediaAssetId: string,\n variantId?: string,\n ctx?: TxContext,\n ): Promise<boolean> {\n const db = this.getDb(ctx);\n const conditions = [\n eq(entityMedia.entityId, entityId),\n eq(entityMedia.mediaAssetId, mediaAssetId),\n ];\n\n if (variantId !== undefined) {\n conditions.push(eq(entityMedia.variantId, variantId));\n }\n\n const result = await db\n .delete(entityMedia)\n .where(and(...conditions))\n .returning();\n\n if (variantId === undefined) {\n return result.some((r) => r.variantId === null);\n }\n return result.length > 0;\n }\n\n async removeAllEntityMedia(entityId: string, ctx?: TxContext): Promise<void> {\n const db = this.getDb(ctx);\n await db.delete(entityMedia).where(eq(entityMedia.entityId, entityId));\n }\n\n async removeAllMediaByAssetId(\n mediaAssetId: string,\n ctx?: TxContext,\n ): Promise<void> {\n const db = this.getDb(ctx);\n await db\n .delete(entityMedia)\n .where(eq(entityMedia.mediaAssetId, mediaAssetId));\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Aggregates\n // ─────────────────────────────────────────────────────────────────────────────\n\n async findAssetsForEntity(\n entityId: string,\n variantId?: string,\n ctx?: TxContext,\n ): Promise<MediaAsset[]> {\n const associations = await this.findEntityMedia(entityId, variantId, ctx);\n const assetIds = associations.map((a) => a.mediaAssetId);\n if (assetIds.length === 0) return [];\n return this.findAssetsByIds(assetIds, ctx);\n }\n}\n",
|
|
100
|
+
"import { resolveOrgId } from \"../../auth/org\";\nimport { assertPermission } from \"../../auth/permissions\";\nimport type { Actor } from \"../../auth/types\";\nimport type { CommerceConfig } from \"../../config/types\";\nimport {\n CommerceNotFoundError,\n CommerceValidationError,\n toCommerceError,\n} from \"../../kernel/errors\";\nimport { runAfterHooks } from \"../../kernel/hooks/executor\";\nimport { createHookContext } from \"../../kernel/hooks/create-context\";\nimport type { HookContext } from \"../../kernel/hooks/types\";\nimport type { HookRegistry } from \"../../kernel/hooks/registry\";\nimport { Err, Ok, type Result } from \"../../kernel/result\";\nimport { createLogger } from \"../../utils/logger\";\nimport type { DatabaseAdapter } from \"../../kernel/database/adapter\";\nimport { createTxContext, type TxContext } from \"../../kernel/database/tx-context\";\nimport {\n InventoryRepository,\n type Warehouse,\n type InventoryLevel,\n} from \"./repository\";\n\nexport type { InventoryAdjustInput, InventoryReserveInput, InventoryReleaseInput } from \"./schemas\";\nimport type { InventoryAdjustInput, InventoryReserveInput, InventoryReleaseInput } from \"./schemas\";\n\nexport interface InventoryServiceDeps {\n repository: InventoryRepository;\n hooks: HookRegistry;\n config: CommerceConfig;\n services: Record<string, unknown>;\n database: DatabaseAdapter;\n}\n\nexport class InventoryService {\n private readonly repo: InventoryRepository;\n\n constructor(private deps: InventoryServiceDeps) {\n this.repo = deps.repository;\n }\n\n private async pickWarehouse(actor?: Actor | null, ctx?: TxContext): Promise<string> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const warehouses = await this.repo.findAllWarehouses(orgId, ctx);\n const sorted = warehouses.sort((a, b) => a.priority - b.priority);\n if (sorted.length > 0) {\n return sorted[0]!.id;\n }\n\n // Create default warehouse if none exists\n const defaultWarehouse = await this.repo.createWarehouse(\n {\n organizationId: orgId,\n name: \"Default Warehouse\",\n code: \"DEFAULT\",\n isActive: true,\n priority: 0,\n metadata: {},\n },\n ctx,\n );\n return defaultWarehouse.id;\n }\n\n async createWarehouse(\n input: Partial<Warehouse>,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Warehouse>> {\n if (!input.name || !input.code) {\n return Err(\n new CommerceValidationError(\"Warehouse name and code are required.\"),\n );\n }\n\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n\n const warehouse = await this.repo.createWarehouse(\n {\n organizationId: orgId,\n name: input.name,\n code: input.code,\n isActive: input.isActive ?? true,\n priority: input.priority ?? 0,\n metadata: input.metadata ?? {},\n ...(input.address !== undefined ? { address: input.address } : {}),\n },\n ctx,\n );\n\n return Ok(warehouse);\n }\n\n async listWarehouses(actor?: Actor | null, ctx?: TxContext): Promise<Result<Warehouse[]>> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const warehouses = await this.repo.findAllWarehouses(orgId, ctx);\n return Ok(warehouses.sort((a, b) => a.priority - b.priority));\n }\n\n async getAvailable(\n entityId: string,\n variantId?: string,\n ctx?: TxContext,\n ): Promise<Result<number>> {\n const available = await this.repo.getAvailableQuantity(\n entityId,\n variantId,\n ctx,\n );\n return Ok(available);\n }\n\n async checkMultiple(\n entityIds: string[],\n ctx?: TxContext,\n ): Promise<Result<Record<string, number>>> {\n const data = await this.repo.getAvailableQuantities(entityIds, ctx);\n return Ok(data);\n }\n\n async getLevelsByEntityId(\n entityId: string,\n ctx?: TxContext,\n ): Promise<Result<InventoryLevel[]>> {\n const levels = await this.repo.findLevelsByEntityId(entityId, ctx);\n return Ok(levels);\n }\n\n async reserve(\n input: InventoryReserveInput,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n if (input.quantity <= 0) {\n return Err(\n new CommerceValidationError(\n \"Reservation quantity must be greater than zero.\",\n ),\n );\n }\n\n const warehouseId = input.warehouseId ?? (await this.pickWarehouse(actor, ctx));\n const performedBy = input.performedBy ?? actor?.userId ?? \"system\";\n const variantId = input.variantId ?? null;\n\n // If we have a transaction context, use the concurrency-safe\n // reserveWithLock (SELECT FOR UPDATE). This is the correct path\n // for checkout — it prevents two concurrent requests from both\n // reserving the last unit.\n if (ctx?.tx) {\n const reserveResult = await this.repo.reserveWithLock(\n input.entityId,\n variantId,\n warehouseId,\n input.quantity,\n ctx,\n );\n\n if (!reserveResult.ok) {\n return Err(new CommerceValidationError(reserveResult.reason));\n }\n\n await this.repo.createMovement(\n {\n entityId: input.entityId,\n warehouseId,\n type: \"reservation\",\n quantity: input.quantity,\n performedBy,\n referenceType: \"order\",\n referenceId: input.orderId,\n ...(input.variantId != null\n ? { variantId: input.variantId }\n : {}),\n },\n ctx,\n );\n\n return Ok(undefined);\n }\n\n // Fallback: no transaction provided. Wrap in a transaction so we can\n // use reserveWithLock (SELECT FOR UPDATE) for concurrency safety.\n const result = await this.deps.database.transaction(async (tx) => {\n const txCtx = createTxContext(tx, { actor: actor ?? null });\n const reserveResult = await this.repo.reserveWithLock(\n input.entityId,\n variantId,\n warehouseId,\n input.quantity,\n txCtx,\n );\n\n if (!reserveResult.ok) {\n return Err(new CommerceValidationError(reserveResult.reason));\n }\n\n await this.repo.createMovement(\n {\n entityId: input.entityId,\n warehouseId,\n type: \"reservation\",\n quantity: input.quantity,\n performedBy,\n referenceType: \"order\",\n referenceId: input.orderId,\n ...(input.variantId != null\n ? { variantId: input.variantId }\n : {}),\n },\n txCtx,\n );\n\n return Ok(undefined);\n });\n\n return result;\n }\n\n async release(\n input: InventoryReleaseInput,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n const warehouseId = input.warehouseId ?? (await this.pickWarehouse(actor, ctx));\n const performedBy = input.performedBy ?? actor?.userId ?? \"system\";\n const variantId = input.variantId ?? null;\n\n const doRelease = async (txCtx: TxContext): Promise<Result<void>> => {\n const releaseResult = await this.repo.releaseWithLock(\n input.entityId,\n variantId,\n warehouseId,\n input.quantity,\n txCtx,\n );\n\n if (!releaseResult.ok) {\n return Err(new CommerceValidationError(releaseResult.reason));\n }\n\n await this.repo.createMovement(\n {\n entityId: input.entityId,\n warehouseId,\n type: \"release\",\n quantity: input.quantity,\n performedBy,\n referenceType: \"order\",\n referenceId: input.orderId,\n ...(input.variantId != null\n ? { variantId: input.variantId }\n : {}),\n },\n txCtx,\n );\n\n return Ok(undefined);\n };\n\n // If we already have a transaction, use it directly\n if (ctx?.tx) {\n return doRelease(ctx);\n }\n\n // Otherwise wrap in a new transaction for locking safety\n return this.deps.database.transaction(async (tx) => {\n return doRelease(createTxContext(tx, { actor: actor ?? null }));\n });\n }\n\n async adjust(\n input: InventoryAdjustInput,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<InventoryLevel>> {\n try {\n assertPermission(actor ?? null, \"inventory:adjust\");\n } catch (error) {\n return Err(toCommerceError(error));\n }\n\n const warehouseId = input.warehouseId ?? (await this.pickWarehouse(actor, ctx));\n\n // Use upsertLevel to create or update\n const existingLevel = await this.repo.findLevelByKey(\n input.entityId,\n warehouseId,\n input.variantId,\n ctx,\n );\n\n let level: InventoryLevel;\n if (existingLevel) {\n const newQuantity = Math.max(\n 0,\n existingLevel.quantityOnHand + input.adjustment,\n );\n const updated = await this.repo.updateLevel(\n existingLevel.id,\n { quantityOnHand: newQuantity },\n ctx,\n );\n level = updated!;\n } else {\n level = await this.repo.createLevel(\n {\n entityId: input.entityId,\n warehouseId,\n quantityOnHand: Math.max(0, input.adjustment),\n quantityReserved: 0,\n quantityIncoming: 0,\n ...(input.variantId !== undefined\n ? { variantId: input.variantId }\n : {}),\n },\n ctx,\n );\n }\n\n await this.repo.createMovement(\n {\n entityId: input.entityId,\n warehouseId,\n type: \"adjustment\",\n quantity: input.adjustment,\n reason: input.reason,\n performedBy: input.performedBy ?? actor?.userId ?? \"system\",\n ...(input.variantId !== undefined\n ? { variantId: input.variantId }\n : {}),\n ...(input.referenceType !== undefined\n ? { referenceType: input.referenceType }\n : {}),\n ...(input.referenceId !== undefined\n ? { referenceId: input.referenceId }\n : {}),\n },\n ctx,\n );\n\n const context: HookContext = createHookContext({\n actor: actor ?? null,\n tx: ctx?.tx ?? null,\n logger: createLogger(\"inventory.adjust\"),\n services: this.deps.services,\n context: { moduleName: \"inventory\" },\n });\n\n const afterHooks = this.deps.hooks.resolve(\"inventory.afterAdjust\");\n await runAfterHooks(\n afterHooks as Parameters<typeof runAfterHooks>[0],\n null,\n level,\n \"update\",\n context,\n );\n\n return Ok(level);\n }\n\n /**\n * Set inventory to an absolute quantity (not a delta).\n *\n * Used by external store webhooks where the source system reports\n * the current stock level (e.g., Shopify sends `{ available: 6 }`).\n * Computes the delta internally so audit movements stay correct.\n */\n async setAbsolute(\n input: {\n entityId: string;\n quantity: number;\n warehouseId?: string;\n variantId?: string;\n reason?: string;\n },\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<InventoryLevel>> {\n const warehouseId = input.warehouseId ?? (await this.pickWarehouse(actor, ctx));\n\n const existingLevel = await this.repo.findLevelByKey(\n input.entityId,\n warehouseId,\n input.variantId,\n ctx,\n );\n\n const currentOnHand = existingLevel?.quantityOnHand ?? 0;\n const delta = input.quantity - currentOnHand;\n\n // Delegate to adjust() so hooks, movements, and permission checks are consistent\n return this.adjust(\n {\n entityId: input.entityId,\n warehouseId,\n adjustment: delta,\n reason: input.reason ?? \"External store absolute inventory sync\",\n ...(input.variantId !== undefined ? { variantId: input.variantId } : {}),\n },\n actor,\n ctx,\n );\n }\n\n /**\n * Deduct inventory on fulfillment (system-level, no permission check).\n *\n * Decrements quantityOnHand for fulfilled items. This is a system\n * operation triggered by order status → fulfilled, not a manual\n * stock adjustment. Creates a \"fulfillment\" type movement for audit.\n *\n * Net effect when paired with release():\n * Before: on_hand=100, reserved=5, available=95\n * After deduct+release: on_hand=95, reserved=0, available=95\n */\n async deductForFulfillment(\n input: {\n entityId: string;\n variantId?: string;\n warehouseId?: string;\n quantity: number;\n orderId: string;\n orgId?: string;\n },\n ctx?: TxContext,\n ): Promise<Result<void>> {\n const warehouseId = input.warehouseId ?? (await this.pickWarehouse(null, ctx));\n const variantId = input.variantId ?? null;\n\n const level = await this.repo.findLevelByKey(\n input.entityId,\n warehouseId,\n variantId != null ? variantId : undefined,\n ctx,\n );\n\n if (!level) {\n // No inventory record — nothing to deduct\n return Ok(undefined);\n }\n\n const newOnHand = Math.max(0, level.quantityOnHand - input.quantity);\n await this.repo.updateLevel(\n level.id,\n { quantityOnHand: newOnHand },\n ctx,\n );\n\n await this.repo.createMovement(\n {\n entityId: input.entityId,\n warehouseId,\n type: \"fulfillment\",\n quantity: -input.quantity,\n performedBy: \"system\",\n referenceType: \"order\",\n referenceId: input.orderId,\n ...(variantId != null ? { variantId } : {}),\n },\n ctx,\n );\n\n return Ok(undefined);\n }\n\n async setUnitCost(\n entityId: string,\n warehouseId: string,\n unitCost: number,\n variantId?: string,\n ctx?: TxContext,\n ): Promise<Result<InventoryLevel>> {\n const level = await this.repo.findLevelByKey(\n entityId,\n warehouseId,\n variantId,\n ctx,\n );\n if (!level) {\n return Err(\n new CommerceNotFoundError(\n `Inventory level not found for entity ${entityId} at warehouse ${warehouseId}.`,\n ),\n );\n }\n const updated = await this.repo.updateLevel(level.id, { unitCost }, ctx);\n return Ok(updated!);\n }\n}\n",
|
|
101
|
+
"import { randomUUID } from \"node:crypto\";\nimport type { Actor } from \"../../auth/types\";\nimport type { DatabaseAdapter } from \"./adapter\";\n\nexport interface TxContext<TTx = unknown> {\n tx: TTx;\n actor: Actor | null;\n requestId: string;\n}\n\nexport interface WithTransactionOptions {\n actor: Actor | null;\n requestId?: string;\n}\n\nexport function createTxContext<TTx>(\n tx: TTx,\n options: WithTransactionOptions,\n): TxContext<TTx> {\n return {\n tx,\n actor: options.actor,\n requestId: options.requestId ?? randomUUID(),\n };\n}\n\nexport async function withTransaction<TDb, TTx, TResult>(\n database: DatabaseAdapter<TDb, TTx>,\n options: WithTransactionOptions,\n fn: (ctx: TxContext<TTx>) => Promise<TResult>,\n): Promise<TResult> {\n return database.transaction(async (tx) => {\n return fn(createTxContext(tx, options));\n });\n}\n\nexport function reuseOrCreateTxContext<TTx>(\n tx: TTx,\n options: WithTransactionOptions,\n existing?: TxContext<TTx> | null,\n): TxContext<TTx> {\n if (existing) {\n return existing;\n }\n return createTxContext(tx, options);\n}\n",
|
|
102
|
+
"import { resolveOrgId } from \"../../auth/org\";\nimport type { Actor } from \"../../auth/types\";\nimport type { StorageAdapter, StoredFile } from \"./adapter\";\nimport { Err, Ok, type Result } from \"../../kernel/result\";\nimport {\n CommerceNotFoundError,\n CommerceValidationError,\n} from \"../../kernel/errors\";\nimport type { MediaRepository } from \"./repository\";\nimport type { CatalogRepository } from \"../catalog/repository\";\nimport type { TxContext } from \"../../kernel/database/tx-context\";\nimport { makeId } from \"../../utils/id\";\n\nexport interface UploadMediaInput {\n filename: string;\n contentType: string;\n data: ArrayBuffer;\n alt?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface AttachMediaInput {\n entityId: string;\n mediaAssetId: string;\n role: \"primary\" | \"gallery\" | \"thumbnail\" | \"video\" | \"document\";\n variantId?: string;\n sortOrder?: number;\n}\n\ninterface MediaServiceDeps {\n repository: MediaRepository;\n catalogRepository: CatalogRepository;\n storage: StorageAdapter;\n}\n\nexport class MediaService {\n private readonly repo: MediaRepository;\n private readonly catalogRepo: CatalogRepository;\n\n constructor(private deps: MediaServiceDeps) {\n this.repo = deps.repository;\n this.catalogRepo = deps.catalogRepository;\n }\n\n async upload(\n input: UploadMediaInput,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<{ id: string; url: string }>> {\n if (!input.filename || !input.contentType) {\n return Err(\n new CommerceValidationError(\"filename and contentType are required.\"),\n );\n }\n\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n\n const id = makeId();\n const key = `${new Date().getFullYear()}/${id}-${input.filename}`;\n const uploaded = await this.deps.storage.upload(\n key,\n input.data,\n input.contentType,\n );\n if (!uploaded.ok) return uploaded as Result<never>;\n\n await this.repo.createAsset(\n {\n organizationId: orgId,\n id,\n storageKey: key,\n filename: input.filename,\n contentType: input.contentType,\n size: input.data.byteLength,\n metadata: input.metadata ?? {},\n uploadedAt: new Date(),\n ...(input.alt !== undefined ? { alt: input.alt } : {}),\n },\n ctx,\n );\n\n const url = await this.deps.storage.getUrl(key);\n if (!url.ok) return url as Result<never>;\n\n return Ok({ id, url: url.value });\n }\n\n async getUrl(id: string, ctx?: TxContext): Promise<Result<string>> {\n const asset = await this.repo.findAssetById(id, ctx);\n if (!asset) return Err(new CommerceNotFoundError(\"Media asset not found.\"));\n return this.deps.storage.getUrl(asset.storageKey);\n }\n\n async getSignedUrl(\n id: string,\n expiresIn = 60 * 15,\n ctx?: TxContext,\n ): Promise<Result<string>> {\n const asset = await this.repo.findAssetById(id, ctx);\n if (!asset) return Err(new CommerceNotFoundError(\"Media asset not found.\"));\n return this.deps.storage.getSignedUrl(asset.storageKey, expiresIn);\n }\n\n async delete(id: string, ctx?: TxContext): Promise<Result<void>> {\n const asset = await this.repo.findAssetById(id, ctx);\n if (!asset) return Err(new CommerceNotFoundError(\"Media asset not found.\"));\n\n const deleted = await this.deps.storage.delete(asset.storageKey);\n if (!deleted.ok) return deleted;\n\n await this.repo.removeAllMediaByAssetId(id, ctx);\n await this.repo.deleteAsset(id, ctx);\n return Ok(undefined);\n }\n\n async list(prefix = \"\"): Promise<Result<StoredFile[]>> {\n const listed = await this.deps.storage.list(prefix);\n if (!listed.ok) return listed;\n return Ok(listed.value);\n }\n\n async attachToEntity(\n input: AttachMediaInput,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n const entity = await this.catalogRepo.findEntityById(input.entityId, ctx);\n if (!entity) {\n return Err(new CommerceNotFoundError(\"Entity not found.\"));\n }\n\n const asset = await this.repo.findAssetById(input.mediaAssetId, ctx);\n if (!asset) {\n return Err(new CommerceNotFoundError(\"Media asset not found.\"));\n }\n\n await this.repo.createEntityMedia(\n {\n entityId: input.entityId,\n mediaAssetId: input.mediaAssetId,\n role: input.role,\n sortOrder: input.sortOrder ?? 0,\n ...(input.variantId !== undefined\n ? { variantId: input.variantId }\n : {}),\n },\n ctx,\n );\n\n return Ok(undefined);\n }\n}\n",
|
|
103
|
+
"import { resolveOrgId } from \"../../auth/org\";\nimport { assertOwnership, assertPermission } from \"../../auth/permissions\";\nimport type { Actor } from \"../../auth/types\";\nimport type { CommerceConfig } from \"../../config/types\";\nimport {\n CommerceNotFoundError,\n CommerceValidationError,\n toCommerceError,\n} from \"../../kernel/errors\";\nimport { runAfterHooks, runBeforeHooks } from \"../../kernel/hooks/executor\";\nimport { createHookContext } from \"../../kernel/hooks/create-context\";\nimport type {\n AfterHook,\n BeforeHook,\n HookContext,\n} from \"../../kernel/hooks/types\";\nimport type { HookRegistry } from \"../../kernel/hooks/registry\";\nimport { Err, Ok, type Result } from \"../../kernel/result\";\nimport { createLogger } from \"../../utils/logger\";\nimport type { TxContext } from \"../../kernel/database/tx-context\";\nimport { CartRepository, type Cart, type CartLineItem } from \"./repository\";\nimport type { CatalogRepository } from \"../catalog/repository\";\n\nexport type {\n CreateCartInput,\n AddCartItemInput,\n UpdateCartItemInput,\n} from \"./schemas\";\n\nimport type {\n CreateCartInput,\n AddCartItemInput,\n UpdateCartItemInput,\n} from \"./schemas\";\n\nimport { defaultCartItemMatcher, type CartItemMatcher } from \"./matcher\";\n\nexport interface CartServiceDeps {\n repository: CartRepository;\n catalogRepository: CatalogRepository;\n hooks: HookRegistry;\n config: CommerceConfig;\n services: Record<string, unknown>;\n cartItemMatcher?: CartItemMatcher;\n}\n\ntype CartAddBeforeHook = BeforeHook<AddCartItemInput>;\ntype CartAddAfterHook = AfterHook<CartLineItem>;\ntype CartRemoveBeforeHook = BeforeHook<CartLineItem>;\ntype CartRemoveAfterHook = AfterHook<CartLineItem>;\ntype CartUpdateBeforeHook = BeforeHook<UpdateCartItemInput>;\ntype CartUpdateAfterHook = AfterHook<CartLineItem>;\n\nfunction makeContext(\n actor: Actor | null,\n services: Record<string, unknown>,\n tx: unknown = null,\n): HookContext {\n return createHookContext({\n actor,\n tx,\n logger: createLogger(\"cart\"),\n services,\n });\n}\n\nfunction isExpired(cart: Cart): boolean {\n return cart.expiresAt.getTime() < Date.now();\n}\n\nexport class CartService {\n private readonly repo: CartRepository;\n private readonly catalogRepo: CatalogRepository;\n\n constructor(private deps: CartServiceDeps) {\n this.repo = deps.repository;\n this.catalogRepo = deps.catalogRepository;\n }\n\n async create(\n input: CreateCartInput,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Cart>> {\n try {\n assertPermission(actor ?? null, \"cart:create\");\n } catch (error) {\n return Err(toCommerceError(error));\n }\n\n const ttlMinutes = this.deps.config.cart?.ttlMinutes ?? 60 * 24 * 7;\n const now = new Date();\n const orgId = resolveOrgId(actor ?? null);\n\n const cart = await this.repo.create(\n {\n organizationId: orgId,\n status: \"active\",\n currency: input.currency ?? \"USD\",\n metadata: input.metadata ?? {},\n expiresAt: new Date(now.getTime() + ttlMinutes * 60 * 1000),\n ...(input.customerId !== undefined\n ? { customerId: input.customerId }\n : {}),\n },\n ctx,\n );\n\n return Ok(cart);\n }\n\n async getById(\n id: string,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Cart & { lineItems: CartLineItem[] }>> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const cart = await this.repo.findById(orgId, id, ctx);\n if (!cart) return Err(new CommerceNotFoundError(\"Cart not found.\"));\n\n // H2 fix: Non-admin actors can only access their own carts.\n // Guest carts (customerId is null) are accessible by anyone (token-gated).\n try {\n this.assertCartOwnership(actor ?? null, cart);\n } catch (error) {\n return Err(toCommerceError(error));\n }\n\n if (isExpired(cart) && cart.status === \"active\") {\n await this.repo.updateStatus(cart.id, \"abandoned\", ctx);\n cart.status = \"abandoned\";\n }\n\n const lineItems = await this.repo.findLineItemsByCartId(id, ctx);\n return Ok({\n ...cart,\n lineItems,\n });\n }\n\n async addItem(\n input: AddCartItemInput,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CartLineItem>> {\n try {\n assertPermission(actor ?? null, \"cart:update\");\n } catch (error) {\n return Err(toCommerceError(error));\n }\n\n const orgId = resolveOrgId(actor ?? null);\n const cart = await this.repo.findById(orgId, input.cartId, ctx);\n if (!cart) return Err(new CommerceNotFoundError(\"Cart not found.\"));\n\n try {\n this.assertCartOwnership(actor ?? null, cart);\n } catch (error) {\n return Err(toCommerceError(error));\n }\n\n if (cart.status !== \"active\") {\n return Err(new CommerceValidationError(\"Cart is not active.\"));\n }\n\n const quantity = input.quantity ?? 1;\n if (quantity <= 0) {\n return Err(\n new CommerceValidationError(\"Quantity must be greater than zero.\"),\n );\n }\n\n // Validate entity exists\n const entity = await this.catalogRepo.findEntityById(input.entityId, ctx);\n if (!entity) return Err(new CommerceNotFoundError(\"Entity not found.\"));\n\n // Check if entity has variants\n const entityVariants = await this.catalogRepo.findVariantsByEntityId(\n input.entityId,\n ctx,\n );\n const hasVariants = entityVariants.length > 0;\n if (hasVariants && !input.variantId) {\n const variantIds = entityVariants.map((v) => v.id);\n return Err(\n new CommerceValidationError(\n `Entity \"${entity.slug}\" has variants enabled, but no variantId was provided.`,\n [\n {\n field: \"variantId\",\n message: `Available variants: ${variantIds.join(\", \")}`,\n },\n ],\n ),\n );\n }\n\n const context = makeContext(actor ?? null, this.deps.services, ctx?.tx);\n const beforeHooks = this.deps.hooks.resolve(\n \"cart.beforeAddItem\",\n ) as CartAddBeforeHook[];\n const afterHooks = this.deps.hooks.resolve(\n \"cart.afterAddItem\",\n ) as CartAddAfterHook[];\n\n const processed = await runBeforeHooks(\n beforeHooks,\n input,\n \"addItem\",\n context,\n );\n\n // CartItemMatcher: deduplicate by merging quantity into existing matching item\n const matcher = this.deps.cartItemMatcher ?? defaultCartItemMatcher;\n const existingItems = await this.repo.findLineItemsByCartId(\n input.cartId,\n ctx,\n );\n const match = existingItems.find((existing) =>\n matcher({\n existingItem: existing,\n newItem: {\n ...processed,\n variantId: processed.variantId ?? null,\n },\n }),\n );\n\n let item: CartLineItem;\n if (match) {\n const updated = await this.repo.updateLineItem(\n match.id,\n { quantity: match.quantity + quantity },\n ctx,\n );\n item = updated!;\n } else {\n item = await this.repo.createLineItem(\n {\n cartId: input.cartId,\n entityId: processed.entityId,\n quantity,\n unitPriceSnapshot: processed.unitPriceSnapshot ?? 1000,\n currency: processed.currency ?? cart.currency,\n metadata: processed.metadata ?? {},\n ...(processed.variantId !== undefined\n ? { variantId: processed.variantId }\n : {}),\n },\n ctx,\n );\n }\n\n await runAfterHooks(afterHooks, null, item, \"addItem\", context);\n\n return Ok(item);\n }\n\n async removeItem(\n cartId: string,\n itemId: string,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n try {\n assertPermission(actor ?? null, \"cart:update\");\n } catch (error) {\n return Err(toCommerceError(error));\n }\n\n const orgId = resolveOrgId(actor ?? null);\n const cart = await this.repo.findById(orgId, cartId, ctx);\n if (!cart) return Err(new CommerceNotFoundError(\"Cart not found.\"));\n\n try {\n this.assertCartOwnership(actor ?? null, cart);\n } catch (error) {\n return Err(toCommerceError(error));\n }\n\n const existing = await this.repo.findLineItemById(itemId, ctx);\n if (!existing || existing.cartId !== cartId) {\n return Err(new CommerceNotFoundError(\"Cart item not found.\"));\n }\n\n const context = makeContext(actor ?? null, this.deps.services, ctx?.tx);\n const beforeHooks = this.deps.hooks.resolve(\n \"cart.beforeRemoveItem\",\n ) as CartRemoveBeforeHook[];\n const afterHooks = this.deps.hooks.resolve(\n \"cart.afterRemoveItem\",\n ) as CartRemoveAfterHook[];\n await runBeforeHooks(beforeHooks, existing, \"removeItem\", context);\n\n await this.repo.deleteLineItem(itemId, ctx);\n\n await runAfterHooks(afterHooks, existing, existing, \"removeItem\", context);\n return Ok(undefined);\n }\n\n async updateQuantity(\n input: UpdateCartItemInput,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CartLineItem>> {\n try {\n assertPermission(actor ?? null, \"cart:update\");\n } catch (error) {\n return Err(toCommerceError(error));\n }\n\n const orgId = resolveOrgId(actor ?? null);\n const cart = await this.repo.findById(orgId, input.cartId, ctx);\n if (!cart) return Err(new CommerceNotFoundError(\"Cart not found.\"));\n\n try {\n this.assertCartOwnership(actor ?? null, cart);\n } catch (error) {\n return Err(toCommerceError(error));\n }\n\n const item = await this.repo.findLineItemById(input.itemId, ctx);\n if (!item || item.cartId !== input.cartId) {\n return Err(new CommerceNotFoundError(\"Cart item not found.\"));\n }\n\n if (input.quantity <= 0) {\n return Err(\n new CommerceValidationError(\"Quantity must be greater than zero.\"),\n );\n }\n\n const context = makeContext(actor ?? null, this.deps.services, ctx?.tx);\n const beforeHooks = this.deps.hooks.resolve(\n \"cart.beforeUpdateQuantity\",\n ) as CartUpdateBeforeHook[];\n const afterHooks = this.deps.hooks.resolve(\n \"cart.afterUpdateQuantity\",\n ) as CartUpdateAfterHook[];\n\n await runBeforeHooks(beforeHooks, input, \"update\", context);\n\n const updated = await this.repo.updateLineItem(\n input.itemId,\n { quantity: input.quantity },\n ctx,\n );\n\n if (!updated) {\n return Err(new CommerceNotFoundError(\"Cart item not found.\"));\n }\n\n await runAfterHooks(afterHooks, item, updated, \"update\", context);\n return Ok(updated);\n }\n\n async merge(\n sourceCartId: string,\n targetCartId: string,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n try {\n assertPermission(actor ?? null, \"cart:update\");\n } catch (error) {\n return Err(toCommerceError(error));\n }\n\n const orgId = resolveOrgId(actor ?? null);\n const source = await this.repo.findById(orgId, sourceCartId, ctx);\n const target = await this.repo.findById(orgId, targetCartId, ctx);\n if (!source || !target)\n return Err(new CommerceNotFoundError(\"Cart not found.\"));\n\n const sourceItems = await this.repo.findLineItemsByCartId(\n sourceCartId,\n ctx,\n );\n\n // Move items from source to target\n for (const item of sourceItems) {\n await this.repo.createLineItem(\n {\n cartId: targetCartId,\n entityId: item.entityId,\n variantId: item.variantId,\n quantity: item.quantity,\n unitPriceSnapshot: item.unitPriceSnapshot,\n currency: item.currency,\n metadata: item.metadata ?? {},\n },\n ctx,\n );\n }\n\n // Clear source cart items and mark as merged\n await this.repo.deleteLineItemsByCartId(sourceCartId, ctx);\n await this.repo.updateStatus(sourceCartId, \"merged\", ctx);\n\n return Ok(undefined);\n }\n\n async abandon(cartId: string, actor?: Actor | null, ctx?: TxContext): Promise<Result<void>> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const cart = await this.repo.findById(orgId, cartId, ctx);\n if (!cart) return Err(new CommerceNotFoundError(\"Cart not found.\"));\n\n await this.repo.updateStatus(cartId, \"abandoned\", ctx);\n return Ok(undefined);\n }\n\n async markAsCheckedOut(\n cartId: string,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const cart = await this.repo.findById(orgId, cartId, ctx);\n if (!cart) return Err(new CommerceNotFoundError(\"Cart not found.\"));\n\n await this.repo.updateStatus(cartId, \"checked_out\", ctx);\n return Ok(undefined);\n }\n\n /**\n * Atomically transitions a cart from \"active\" to \"checking_out\".\n * Returns Err if the cart was already claimed by a concurrent checkout.\n * This prevents TOCTOU race conditions on double-checkout.\n */\n async claimForCheckout(\n cartId: string,\n ctx?: TxContext,\n ): Promise<Result<Cart>> {\n const claimed = await this.repo.transitionToCheckingOut(cartId, ctx);\n if (!claimed) {\n return Err(\n new CommerceValidationError(\n \"Cart is not available for checkout. It may have already been checked out by a concurrent request.\",\n ),\n );\n }\n return Ok(claimed);\n }\n\n /**\n * Creates an anonymous guest cart with a secret token for access control.\n * The secret must be stored client-side (cookie/local storage) and sent\n * with subsequent requests to identify the cart owner.\n */\n async createGuestCart(\n currency = \"USD\",\n ctx?: TxContext,\n ): Promise<Result<{ cart: Cart; secret: string }>> {\n const secret = crypto.randomUUID();\n const ttlMinutes = this.deps.config.cart?.ttlMinutes ?? 60 * 24 * 7;\n const now = new Date();\n\n const cart = await this.repo.create(\n {\n organizationId: resolveOrgId(null),\n customerId: undefined,\n status: \"active\",\n currency,\n secret,\n metadata: {},\n expiresAt: new Date(now.getTime() + ttlMinutes * 60 * 1000),\n },\n ctx,\n );\n\n return Ok({ cart, secret });\n }\n\n /**\n * Merges a guest (source) cart into an authenticated (target) cart on login.\n * Uses addItem() internally so CartItemMatcher deduplication is applied.\n * The source cart's secret must be provided for access control.\n */\n async mergeCarts(\n targetCartId: string,\n sourceCartId: string,\n sourceSecret: string,\n actor: Actor,\n ctx?: TxContext,\n ): Promise<Result<Cart>> {\n const orgId = resolveOrgId(actor);\n const sourceCart = await this.repo.findById(orgId, sourceCartId, ctx);\n if (!sourceCart || sourceCart.secret !== sourceSecret) {\n return Err(\n new CommerceValidationError(\"Invalid cart or cart secret.\"),\n );\n }\n\n const targetCart = await this.repo.findById(orgId, targetCartId, ctx);\n if (!targetCart) {\n return Err(new CommerceNotFoundError(\"Target cart not found.\"));\n }\n\n const sourceItems = await this.repo.findLineItemsByCartId(\n sourceCartId,\n ctx,\n );\n\n for (const item of sourceItems) {\n await this.addItem(\n {\n cartId: targetCartId,\n entityId: item.entityId,\n quantity: item.quantity,\n ...(item.variantId != null ? { variantId: item.variantId } : {}),\n unitPriceSnapshot: item.unitPriceSnapshot,\n currency: item.currency,\n metadata: item.metadata ?? {},\n },\n actor,\n ctx,\n );\n }\n\n // Mark source cart as merged\n await this.repo.updateStatus(sourceCartId, \"merged\", ctx);\n\n const mergedCart = await this.repo.findById(orgId, targetCartId, ctx);\n return Ok(mergedCart!);\n }\n\n /**\n * Asserts the actor owns the cart. Bypassed for:\n * - Admin/staff actors (permissions include `*:*`)\n * - Guest carts (customerId is null) — access is token-gated instead\n * - Null actors (unauthenticated guest access)\n */\n private assertCartOwnership(actor: Actor | null, cart: Cart): void {\n // Guest carts have no customerId — access is controlled by cart secret/token\n if (cart.customerId == null) return;\n // Unauthenticated access to a customer cart is blocked by assertPermission elsewhere\n if (!actor) return;\n // Admin/staff bypass\n assertOwnership(actor, cart.customerId);\n }\n}\n",
|
|
104
|
+
"import type { CartLineItem } from \"./repository\";\n\n/**\n * Determines whether a new item matches an existing cart line item.\n * Used by addItem to decide whether to increment quantity (match)\n * or insert a new line (no match).\n *\n * The default matcher compares entityId + variantId.\n * Developers selling customizable products (engraving, gift notes)\n * can provide a custom matcher that includes metadata fields.\n */\nexport type CartItemMatcher = (args: {\n existingItem: CartLineItem;\n newItem: {\n entityId: string;\n variantId: string | null;\n [key: string]: unknown;\n };\n}) => boolean;\n\nexport const defaultCartItemMatcher: CartItemMatcher = ({\n existingItem,\n newItem,\n}) =>\n existingItem.entityId === newItem.entityId &&\n existingItem.variantId === (newItem.variantId ?? null);\n",
|
|
105
|
+
"import { resolveOrgId } from \"../../auth/org\";\nimport { assertOwnership, assertPermission } from \"../../auth/permissions\";\nimport type { Actor } from \"../../auth/types\";\nimport {\n CommerceInvalidTransitionError,\n CommerceNotFoundError,\n CommerceValidationError,\n toCommerceError,\n} from \"../../kernel/errors\";\nimport { runAfterHooks, runBeforeHooks } from \"../../kernel/hooks/executor\";\nimport { createHookContext } from \"../../kernel/hooks/create-context\";\nimport type {\n AfterHook,\n BeforeHook,\n HookContext,\n} from \"../../kernel/hooks/types\";\nimport type { HookRegistry } from \"../../kernel/hooks/registry\";\nimport {\n canTransition,\n orderStateMachine,\n type OrderState,\n type StateDefinition,\n} from \"../../kernel/state-machine/machine\";\nimport { Err, Ok, type Result } from \"../../kernel/result\";\nimport { createLogger } from \"../../utils/logger\";\nimport { paginate, type Pagination } from \"../../utils/pagination\";\nimport type { TxContext } from \"../../kernel/database/tx-context\";\nimport type { PluginDb } from \"../../kernel/database/plugin-types\";\nimport {\n OrdersRepository,\n type Order,\n type OrderLineItem,\n type OrderStatusHistory,\n} from \"./repository\";\n\nexport interface CreateOrderInput {\n customerId?: string;\n currency: string;\n subtotal: number;\n taxTotal: number;\n shippingTotal: number;\n discountTotal?: number;\n grandTotal: number;\n paymentIntentId?: string | undefined;\n paymentMethodId?: string | undefined;\n metadata?: Record<string, unknown>;\n lineItems: Array<{\n entityId: string;\n entityType: string;\n variantId?: string;\n sku?: string;\n title: string;\n quantity: number;\n unitPrice: number;\n totalPrice: number;\n taxAmount?: number;\n discountAmount?: number;\n metadata?: Record<string, unknown>;\n }>;\n}\n\nexport interface ListOrdersParams {\n page?: number;\n limit?: number;\n status?: string;\n}\n\nexport interface ChangeStatusInput {\n orderId: string;\n newStatus: OrderState;\n reason?: string;\n}\n\nexport interface OrderServiceDeps {\n repository: OrdersRepository;\n hooks: HookRegistry;\n services: Record<string, unknown>;\n /** Custom state machine. If provided, overrides the default order transitions. */\n stateMachine?: StateDefinition<string>;\n /** Kernel database reference for hook contexts. Uses PluginDb to avoid circular Kernel import. */\n kernel?: { database: { db: PluginDb } };\n}\n\nexport type HydratedOrder = Order & { lineItems: OrderLineItem[] };\ntype OrderListResult = { items: HydratedOrder[]; pagination: Pagination };\ntype BeforeCreateOrderHook = BeforeHook<CreateOrderInput>;\ntype AfterCreateOrderHook = AfterHook<HydratedOrder>;\ntype StatusChangeHookInput = {\n orderId: string;\n fromStatus: OrderState;\n newStatus: OrderState;\n reason?: string;\n};\ntype BeforeStatusChangeHook = BeforeHook<StatusChangeHookInput>;\ntype AfterStatusChangeHook = AfterHook<HydratedOrder>;\n\nfunction context(\n actor: Actor | null,\n services: Record<string, unknown>,\n tx: unknown = null,\n kernel: { database: { db: PluginDb } } | null = null,\n): HookContext {\n return createHookContext({\n actor,\n tx,\n logger: createLogger(\"orders\"),\n services,\n context: { moduleName: \"orders\" },\n ...(kernel != null ? { kernel } : {}),\n });\n}\n\nexport class OrderService {\n private readonly repo: OrdersRepository;\n private readonly machine: StateDefinition<string>;\n\n constructor(private deps: OrderServiceDeps) {\n this.repo = deps.repository;\n this.machine = deps.stateMachine ?? orderStateMachine;\n }\n\n private async hydrateOrder(\n order: Order,\n ctx?: TxContext,\n ): Promise<HydratedOrder> {\n const lineItems = await this.repo.findLineItemsByOrderId(order.id, ctx);\n return { ...order, lineItems };\n }\n\n async create(\n input: CreateOrderInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<HydratedOrder>> {\n try {\n assertPermission(actor, \"orders:create\");\n } catch (error) {\n return Err(toCommerceError(error));\n }\n\n if (input.lineItems.length === 0) {\n return Err(\n new CommerceValidationError(\"Order requires at least one line item.\"),\n );\n }\n\n const beforeHooks = this.deps.hooks.resolve(\n \"orders.beforeCreate\",\n ) as BeforeCreateOrderHook[];\n const afterHooks = this.deps.hooks.resolve(\n \"orders.afterCreate\",\n ) as AfterCreateOrderHook[];\n const hookCtx = context(actor, this.deps.services, ctx?.tx, this.deps.kernel);\n\n const processed = await runBeforeHooks(\n beforeHooks,\n input,\n \"create\",\n hookCtx,\n );\n\n const orderNumber = await this.repo.getNextOrderNumber(ctx);\n const orgId = resolveOrgId(actor);\n\n const order = await this.repo.create(\n {\n organizationId: orgId,\n orderNumber,\n status: \"pending\",\n currency: processed.currency,\n subtotal: processed.subtotal,\n taxTotal: processed.taxTotal,\n shippingTotal: processed.shippingTotal,\n discountTotal: processed.discountTotal ?? 0,\n grandTotal: processed.grandTotal,\n ...(processed.paymentIntentId != null ? { paymentIntentId: processed.paymentIntentId } : {}),\n ...(processed.paymentMethodId != null ? { paymentMethodId: processed.paymentMethodId } : {}),\n metadata: processed.metadata ?? {},\n placedAt: new Date(),\n ...(processed.customerId !== undefined\n ? { customerId: processed.customerId }\n : {}),\n },\n ctx,\n );\n\n const lineItemsData = processed.lineItems.map((item) => ({\n orderId: order.id,\n entityId: item.entityId,\n entityType: item.entityType,\n title: item.title,\n quantity: item.quantity,\n unitPrice: item.unitPrice,\n totalPrice: item.totalPrice,\n taxAmount: item.taxAmount ?? 0,\n discountAmount: item.discountAmount ?? 0,\n fulfillmentStatus: \"unfulfilled\" as const,\n metadata: item.metadata ?? {},\n ...(item.variantId !== undefined ? { variantId: item.variantId } : {}),\n ...(item.sku !== undefined ? { sku: item.sku } : {}),\n }));\n\n await this.repo.createLineItems(lineItemsData, ctx);\n\n await this.repo.createStatusHistory(\n {\n orderId: order.id,\n fromStatus: \"pending\",\n toStatus: \"pending\",\n reason: \"order_created\",\n changedBy: actor?.userId ?? \"system\",\n },\n ctx,\n );\n\n const hydrated = await this.hydrateOrder(order, ctx);\n const report = await runAfterHooks(\n afterHooks,\n null,\n hydrated,\n \"create\",\n hookCtx,\n );\n\n return Ok(\n hydrated,\n report.hasErrors ? { hookErrors: report.errors } : undefined,\n );\n }\n\n async getById(\n id: string,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<HydratedOrder>> {\n const orgId = resolveOrgId(actor);\n const order = await this.repo.findById(orgId, id, ctx);\n if (!order) return Err(new CommerceNotFoundError(\"Order not found.\"));\n\n try {\n if (\n actor?.permissions.includes(\"orders:read\") ||\n actor?.permissions.includes(\"*:*\")\n ) {\n // no-op\n } else if (actor?.permissions.includes(\"orders:read:own\")) {\n assertOwnership(actor, order.customerId ?? null);\n } else {\n assertPermission(actor, \"orders:read\");\n }\n } catch (error) {\n return Err(toCommerceError(error));\n }\n\n const hydrated = await this.hydrateOrder(order, ctx);\n\n // Run afterGet hooks — allows plugins to enrich the order (e.g., vendor fulfillment)\n const afterGetHooks = this.deps.hooks.resolve(\n \"orders.afterGet\",\n ) as AfterHook<HydratedOrder>[];\n if (afterGetHooks.length > 0) {\n const hookCtx = context(actor, this.deps.services, ctx?.tx, this.deps.kernel);\n await runAfterHooks(afterGetHooks, null, hydrated, \"read\", hookCtx);\n }\n\n return Ok(hydrated);\n }\n\n async getByNumber(\n orderNumber: string,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<HydratedOrder>> {\n const orgId = resolveOrgId(actor);\n const order = await this.repo.findByOrderNumber(orgId, orderNumber, ctx);\n if (!order) return Err(new CommerceNotFoundError(\"Order not found.\"));\n return this.getById(order.id, actor, ctx);\n }\n\n async list(\n params: ListOrdersParams,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<OrderListResult>> {\n try {\n assertPermission(actor, \"orders:read\");\n } catch (error) {\n return Err(toCommerceError(error));\n }\n\n const orgId = resolveOrgId(actor);\n let items: Order[];\n if (params.status) {\n items = await this.repo.findByStatus(orgId, params.status, ctx);\n } else {\n items = await this.repo.findAll(orgId, undefined, ctx);\n }\n\n // Sort by placedAt descending (in-memory, as findAll already sorts)\n items.sort((a, b) => b.placedAt.getTime() - a.placedAt.getTime());\n\n const paged = paginate(items, params.page ?? 1, params.limit ?? 20);\n const hydratedItems = await Promise.all(\n paged.items.map((order) => this.hydrateOrder(order, ctx)),\n );\n\n return Ok({\n items: hydratedItems,\n pagination: paged.pagination,\n });\n }\n\n async listByCustomer(\n customerId: string,\n params: ListOrdersParams,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<OrderListResult>> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n let items = await this.repo.findByCustomerId(orgId, customerId, ctx);\n\n if (params.status) {\n items = items.filter((order) => order.status === params.status);\n }\n\n items.sort((a, b) => b.placedAt.getTime() - a.placedAt.getTime());\n const paged = paginate(items, params.page ?? 1, params.limit ?? 20);\n const hydratedItems = await Promise.all(\n paged.items.map((order) => this.hydrateOrder(order, ctx)),\n );\n\n return Ok({\n items: hydratedItems,\n pagination: paged.pagination,\n });\n }\n\n async changeStatus(\n input: ChangeStatusInput,\n actor: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<HydratedOrder>> {\n const orgId = resolveOrgId(actor);\n const order = await this.repo.findById(orgId, input.orderId, ctx);\n if (!order) return Err(new CommerceNotFoundError(\"Order not found.\"));\n\n try {\n assertPermission(actor, \"orders:update\");\n } catch (error) {\n return Err(toCommerceError(error));\n }\n\n if (\n !canTransition(\n this.machine,\n order.status as OrderState,\n input.newStatus,\n )\n ) {\n return Err(\n new CommerceInvalidTransitionError(\n `Cannot transition from ${order.status} to ${input.newStatus}.`,\n ),\n );\n }\n\n const beforeHooks = this.deps.hooks.resolve(\n \"orders.beforeStatusChange\",\n ) as BeforeStatusChangeHook[];\n const afterHooks = this.deps.hooks.resolve(\n \"orders.afterStatusChange\",\n ) as AfterStatusChangeHook[];\n\n const hookCtx = context(actor, this.deps.services, ctx?.tx, this.deps.kernel);\n const statusHookInput: StatusChangeHookInput = {\n orderId: order.id,\n fromStatus: order.status as OrderState,\n newStatus: input.newStatus,\n ...(input.reason !== undefined ? { reason: input.reason } : {}),\n };\n\n await runBeforeHooks(beforeHooks, statusHookInput, \"statusChange\", hookCtx);\n\n const previous = order.status;\n const lineItems = await this.repo.findLineItemsByOrderId(order.id, ctx);\n\n // Handle cancellation and refund side effects\n if (input.newStatus === \"cancelled\" || input.newStatus === \"refunded\") {\n // 1. Release inventory reservations\n const inventory = this.deps.services.inventory as\n | {\n release(input: {\n entityId: string;\n variantId?: string;\n quantity: number;\n orderId: string;\n performedBy?: string;\n }): Promise<unknown>;\n }\n | undefined;\n\n if (inventory?.release) {\n for (const lineItem of lineItems) {\n // Only release inventory for unfulfilled items.\n // Fulfilled items had their reservation released during the\n // fulfilled transition — releasing again would double-release.\n if (lineItem.fulfillmentStatus === \"unfulfilled\") {\n await inventory.release({\n entityId: lineItem.entityId,\n quantity: lineItem.quantity,\n orderId: order.id,\n performedBy: actor?.userId ?? \"system\",\n ...(lineItem.variantId != null\n ? { variantId: lineItem.variantId }\n : {}),\n });\n }\n }\n }\n\n // 2. Refund payment (if captured)\n const paymentIntentId =\n (order as Record<string, unknown>).paymentIntentId as string | undefined\n ?? (order.metadata as Record<string, unknown> | null)?.paymentIntentId as string | undefined;\n\n if (paymentIntentId) {\n const payments = this.deps.services.payments as\n | {\n refund(\n paymentId: string,\n amount: number,\n reason?: string,\n ): Promise<unknown>;\n }\n | undefined;\n\n if (payments?.refund) {\n await payments.refund(\n paymentIntentId,\n order.grandTotal,\n input.reason ?? `order_${input.newStatus}`,\n );\n }\n }\n\n // 3. Void tax transaction\n const tax = this.deps.services.tax as\n | {\n voidTransaction(input: { transactionId: string }): Promise<unknown>;\n }\n | undefined;\n if (tax?.voidTransaction) {\n await tax.voidTransaction({ transactionId: order.id });\n }\n }\n\n // Handle fulfillment: deduct on_hand and release reservations.\n // Items have been shipped — on_hand decreases (stock left the warehouse)\n // and reservations are cleared (no longer needed).\n //\n // Net effect per line item:\n // on_hand -= quantity, reserved -= quantity, available unchanged\n // Before: on_hand=100, reserved=5, available=95\n // After: on_hand=95, reserved=0, available=95\n if (input.newStatus === \"fulfilled\" || input.newStatus === \"partially_fulfilled\") {\n const inventory = this.deps.services.inventory as\n | {\n deductForFulfillment(input: {\n entityId: string;\n variantId?: string;\n quantity: number;\n orderId: string;\n }): Promise<unknown>;\n release(input: {\n entityId: string;\n variantId?: string;\n quantity: number;\n orderId: string;\n performedBy?: string;\n }): Promise<unknown>;\n }\n | undefined;\n\n if (inventory) {\n for (const lineItem of lineItems) {\n if (lineItem.fulfillmentStatus === \"unfulfilled\") {\n // Deduct on_hand (stock physically left warehouse)\n await inventory.deductForFulfillment({\n entityId: lineItem.entityId,\n quantity: lineItem.quantity,\n orderId: order.id,\n ...(lineItem.variantId != null\n ? { variantId: lineItem.variantId }\n : {}),\n });\n\n // Release reservation (no longer needed)\n await inventory.release({\n entityId: lineItem.entityId,\n quantity: lineItem.quantity,\n orderId: order.id,\n performedBy: actor?.userId ?? \"system\",\n ...(lineItem.variantId != null\n ? { variantId: lineItem.variantId }\n : {}),\n });\n\n // Mark line item as fulfilled\n await this.repo.updateLineItem(\n lineItem.id,\n { fulfillmentStatus: \"fulfilled\" },\n ctx,\n );\n }\n }\n }\n }\n\n // Update order status with atomic guard on current status\n const updated = await this.repo.updateStatus(\n order.id,\n previous,\n input.newStatus,\n ctx,\n );\n if (!updated) {\n return Err(new CommerceValidationError(\n `Order status changed concurrently. Refresh and retry.`,\n ));\n }\n\n await this.repo.createStatusHistory(\n {\n orderId: order.id,\n fromStatus: previous,\n toStatus: input.newStatus,\n changedBy: actor?.userId ?? \"system\",\n ...(input.reason !== undefined ? { reason: input.reason } : {}),\n },\n ctx,\n );\n\n // Audit logging is now automatic via audit hooks (RFC-005)\n // registered in kernel boot — no manual audit.record() needed.\n\n const hydrated = await this.hydrateOrder(updated, ctx);\n const report = await runAfterHooks(\n afterHooks,\n null,\n hydrated,\n \"statusChange\",\n hookCtx,\n );\n\n return Ok(\n hydrated,\n report.hasErrors ? { hookErrors: report.errors } : undefined,\n );\n }\n\n async cancel(\n orderId: string,\n actor: Actor | null,\n reason = \"cancelled_by_user\",\n ctx?: TxContext,\n ): Promise<Result<HydratedOrder>> {\n return this.changeStatus(\n { orderId, newStatus: \"cancelled\", reason },\n actor,\n ctx,\n );\n }\n\n async refund(\n orderId: string,\n actor: Actor | null,\n reason = \"refunded\",\n ctx?: TxContext,\n ): Promise<Result<HydratedOrder>> {\n return this.changeStatus(\n { orderId, newStatus: \"refunded\", reason },\n actor,\n ctx,\n );\n }\n\n async getStatusHistory(\n orderId: string,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<OrderStatusHistory[]>> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const order = await this.repo.findById(orgId, orderId, ctx);\n if (!order) {\n return Err(new CommerceNotFoundError(\"Order not found.\"));\n }\n\n const items = await this.repo.findStatusHistoryByOrderId(orderId, ctx);\n // Sort by changedAt ascending (oldest first)\n items.sort((a, b) => a.changedAt.getTime() - b.changedAt.getTime());\n\n return Ok(items);\n }\n\n async updateOrder(\n orderId: string,\n data: { placedAt?: Date; metadata?: Record<string, unknown> },\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Order>> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const order = await this.repo.findById(orgId, orderId, ctx);\n if (!order) {\n return Err(new CommerceNotFoundError(\"Order not found.\"));\n }\n const updated = await this.repo.update(orderId, data, ctx);\n return Ok(updated!);\n }\n}\n",
|
|
106
|
+
"import { CommerceValidationError } from \"../../kernel/errors\";\nimport { Err, Ok, type Result } from \"../../kernel/result\";\nimport type {\n CreatePaymentIntentParams,\n PaymentAdapter,\n PaymentCapture,\n PaymentIntent,\n PaymentRefund,\n} from \"./adapter\";\n\nexport class PaymentsService {\n private readonly adapterMap: Map<string, PaymentAdapter>;\n private readonly defaultAdapter: PaymentAdapter | undefined;\n\n constructor(adapters: PaymentAdapter[] | undefined) {\n this.adapterMap = new Map();\n for (const adapter of adapters ?? []) {\n this.adapterMap.set(adapter.providerId, adapter);\n }\n this.defaultAdapter = adapters?.[0];\n }\n\n /**\n * Resolve a specific adapter by its providerId.\n * Falls back to the default (first) adapter only when paymentMethodId is omitted.\n */\n private resolveAdapter(paymentMethodId?: string): Result<PaymentAdapter> {\n if (paymentMethodId) {\n const adapter = this.adapterMap.get(paymentMethodId);\n if (!adapter) {\n return Err(\n new CommerceValidationError(\n `No payment adapter registered for provider \"${paymentMethodId}\". ` +\n `Available: [${[...this.adapterMap.keys()].join(\", \")}]`,\n ),\n );\n }\n return Ok(adapter);\n }\n if (!this.defaultAdapter) {\n return Err(new CommerceValidationError(\"No payment adapter configured.\"));\n }\n return Ok(this.defaultAdapter);\n }\n\n /** Expose registered provider IDs for validation hooks. */\n get registeredProviderIds(): string[] {\n return [...this.adapterMap.keys()];\n }\n\n async authorize(\n params: Omit<CreatePaymentIntentParams, \"orderId\"> & {\n paymentMethodId?: string;\n metadata?: Record<string, unknown>;\n },\n ): Promise<Result<PaymentIntent>> {\n const adapter = this.resolveAdapter(params.paymentMethodId);\n if (!adapter.ok) return adapter;\n\n return adapter.value.createPaymentIntent({\n ...params,\n orderId: String(params.metadata?.orderId ?? \"pending-order\"),\n metadata: Object.fromEntries(\n Object.entries(params.metadata ?? {}).map(([key, value]) => [\n key,\n String(value),\n ]),\n ),\n });\n }\n\n async capture(\n paymentIntentId: string,\n amount?: number,\n paymentMethodId?: string,\n ): Promise<Result<PaymentCapture>> {\n const adapter = this.resolveAdapter(paymentMethodId);\n if (!adapter.ok) return adapter;\n return adapter.value.capturePayment(paymentIntentId, amount);\n }\n\n async refund(\n paymentId: string,\n amount: number,\n reason?: string,\n paymentMethodId?: string,\n ): Promise<Result<PaymentRefund>> {\n const adapter = this.resolveAdapter(paymentMethodId);\n if (!adapter.ok) return adapter;\n return adapter.value.refundPayment(paymentId, amount, reason);\n }\n\n async cancel(\n paymentIntentId: string,\n paymentMethodId?: string,\n ): Promise<Result<void>> {\n const adapter = this.resolveAdapter(paymentMethodId);\n if (!adapter.ok) return adapter;\n return adapter.value.cancelPaymentIntent(paymentIntentId);\n }\n\n async verifyWebhook(request: Request) {\n const adapter = this.resolveAdapter();\n if (!adapter.ok) return adapter;\n return adapter.value.verifyWebhook(request);\n }\n}\n",
|
|
107
|
+
"import { createHmac } from \"node:crypto\";\nimport { resolveOrgId } from \"../../auth/org\";\nimport type { Actor } from \"../../auth/types\";\nimport { CommerceNotFoundError } from \"../../kernel/errors\";\nimport { Err, Ok, type Result } from \"../../kernel/result\";\nimport type { TxContext } from \"../../kernel/database/tx-context\";\nimport type { FulfillmentRepository } from \"./repository\";\nimport type { OrdersRepository } from \"../orders/repository\";\nimport type {\n FulfillmentLineItem,\n FulfillmentRecord,\n FulfillmentStrategy,\n FulfillmentStrategyContext,\n} from \"./types\";\nimport { makeId } from \"../../utils/id\";\n\ninterface InventoryServiceLike {\n adjust(input: {\n entityId: string;\n variantId?: string;\n warehouseId?: string;\n adjustment: number;\n reason: string;\n referenceType?: string;\n referenceId?: string;\n }, actor?: unknown): Promise<unknown>;\n release(input: {\n entityId: string;\n variantId?: string;\n quantity: number;\n orderId: string;\n performedBy?: string;\n }): Promise<unknown>;\n}\n\ninterface FulfillmentServiceDeps {\n repository: FulfillmentRepository;\n ordersRepository: OrdersRepository;\n inventoryService?: InventoryServiceLike;\n}\n\nfunction toFulfillmentLineItem(lineItem: FulfillmentLineItem): {\n id: string;\n title: string;\n quantity: number;\n sku?: string;\n} {\n return {\n id: lineItem.id,\n title: lineItem.title,\n quantity: lineItem.quantity,\n ...(lineItem.sku != null ? { sku: lineItem.sku } : {}),\n };\n}\n\nclass PhysicalFulfillmentStrategy implements FulfillmentStrategy {\n type = \"physical\";\n\n async canFulfill(\n _lineItem: FulfillmentLineItem,\n _context: FulfillmentStrategyContext,\n ): Promise<Result<boolean>> {\n return Ok(true);\n }\n\n async fulfill(\n lineItem: FulfillmentLineItem,\n _context: FulfillmentStrategyContext,\n ): Promise<Result<FulfillmentRecord>> {\n return Ok({\n id: makeId(),\n orderId: lineItem.orderId,\n type: this.type,\n status: \"pending\",\n lineItems: [toFulfillmentLineItem(lineItem)],\n });\n }\n\n async reverse(\n _fulfillmentId: string,\n _context: FulfillmentStrategyContext,\n ): Promise<Result<void>> {\n return Ok(undefined);\n }\n}\n\nclass DigitalDownloadFulfillmentStrategy implements FulfillmentStrategy {\n type = \"digital-download\";\n\n async canFulfill(\n _lineItem: FulfillmentLineItem,\n _context: FulfillmentStrategyContext,\n ): Promise<Result<boolean>> {\n return Ok(true);\n }\n\n async fulfill(\n lineItem: FulfillmentLineItem,\n _context: FulfillmentStrategyContext,\n ): Promise<Result<FulfillmentRecord>> {\n const expiresAt = new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString();\n return Ok({\n id: makeId(),\n orderId: lineItem.orderId,\n type: this.type,\n status: \"fulfilled\",\n downloadUrl: `https://downloads.local/${lineItem.id}?token=${createHmac(\"sha256\", \"download\").update(lineItem.id).digest(\"hex\")}`,\n downloadExpiresAt: expiresAt,\n maxDownloads: 5,\n downloadCount: 0,\n lineItems: [toFulfillmentLineItem(lineItem)],\n entityType: \"digitalDownload\",\n entityId: lineItem.entityId,\n ...(lineItem.customerId !== undefined\n ? { customerId: lineItem.customerId }\n : {}),\n });\n }\n\n async reverse(\n _fulfillmentId: string,\n _context: FulfillmentStrategyContext,\n ): Promise<Result<void>> {\n return Ok(undefined);\n }\n}\n\nclass DigitalAccessFulfillmentStrategy implements FulfillmentStrategy {\n type = \"digital-access\";\n\n async canFulfill(\n _lineItem: FulfillmentLineItem,\n _context: FulfillmentStrategyContext,\n ): Promise<Result<boolean>> {\n return Ok(true);\n }\n\n async fulfill(\n lineItem: FulfillmentLineItem,\n _context: FulfillmentStrategyContext,\n ): Promise<Result<FulfillmentRecord>> {\n return Ok({\n id: makeId(),\n orderId: lineItem.orderId,\n type: this.type,\n status: \"fulfilled\",\n lineItems: [toFulfillmentLineItem(lineItem)],\n entityType: \"course\",\n entityId: lineItem.entityId,\n ...(lineItem.customerId !== undefined\n ? { customerId: lineItem.customerId }\n : {}),\n isActive: true,\n grantedAt: new Date().toISOString(),\n });\n }\n\n async reverse(\n _fulfillmentId: string,\n _context: FulfillmentStrategyContext,\n ): Promise<Result<void>> {\n return Ok(undefined);\n }\n}\n\nclass InternalTransferFulfillmentStrategy implements FulfillmentStrategy {\n type = \"internal-transfer\";\n\n async canFulfill(\n _lineItem: FulfillmentLineItem,\n _context: FulfillmentStrategyContext,\n ): Promise<Result<boolean>> {\n return Ok(true);\n }\n\n async fulfill(\n lineItem: FulfillmentLineItem,\n _context: FulfillmentStrategyContext,\n ): Promise<Result<FulfillmentRecord>> {\n return Ok({\n id: makeId(),\n orderId: lineItem.orderId,\n type: this.type,\n status: \"processing\",\n lineItems: [toFulfillmentLineItem(lineItem)],\n });\n }\n\n async reverse(\n _fulfillmentId: string,\n _context: FulfillmentStrategyContext,\n ): Promise<Result<void>> {\n return Ok(undefined);\n }\n}\n\nclass AppointmentFulfillmentStrategy implements FulfillmentStrategy {\n type = \"appointment\";\n\n async canFulfill(\n _lineItem: FulfillmentLineItem,\n _context: FulfillmentStrategyContext,\n ): Promise<Result<boolean>> {\n return Ok(true);\n }\n\n async fulfill(\n lineItem: FulfillmentLineItem,\n _context: FulfillmentStrategyContext,\n ): Promise<Result<FulfillmentRecord>> {\n return Ok({\n id: makeId(),\n orderId: lineItem.orderId,\n type: this.type,\n status: \"pending\",\n lineItems: [toFulfillmentLineItem(lineItem)],\n });\n }\n\n async reverse(\n _fulfillmentId: string,\n _context: FulfillmentStrategyContext,\n ): Promise<Result<void>> {\n return Ok(undefined);\n }\n}\n\nexport class FulfillmentService {\n private strategies = new Map<string, FulfillmentStrategy>();\n\n constructor(private deps: FulfillmentServiceDeps) {\n this.strategies.set(\"physical\", new PhysicalFulfillmentStrategy());\n this.strategies.set(\n \"digital-download\",\n new DigitalDownloadFulfillmentStrategy(),\n );\n this.strategies.set(\n \"digital-access\",\n new DigitalAccessFulfillmentStrategy(),\n );\n this.strategies.set(\n \"internal-transfer\",\n new InternalTransferFulfillmentStrategy(),\n );\n this.strategies.set(\"appointment\", new AppointmentFulfillmentStrategy());\n }\n\n async fulfillOrder(orderId: string, actor?: Actor | null, ctx?: TxContext): Promise<Result<void>> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const order = await this.deps.ordersRepository.findById(orgId, orderId, ctx);\n if (!order) return Err(new CommerceNotFoundError(\"Order not found.\"));\n\n const lineItems = await this.deps.ordersRepository.findLineItemsByOrderId(\n orderId,\n ctx,\n );\n\n for (const lineItem of lineItems) {\n const strategyId =\n lineItem.entityType === \"digitalDownload\"\n ? \"digital-download\"\n : lineItem.entityType === \"course\"\n ? \"digital-access\"\n : lineItem.entityType === \"internalAsset\"\n ? \"internal-transfer\"\n : \"physical\";\n const strategy = this.strategies.get(strategyId)!;\n const result = await strategy.fulfill(\n {\n ...lineItem,\n orderId,\n ...(order.customerId != null ? { customerId: order.customerId } : {}),\n },\n {},\n );\n if (!result.ok) return result;\n\n const record = result.value;\n\n // Persist the fulfillment record via repository\n const created = await this.deps.repository.create(\n {\n id: record.id,\n orderId: record.orderId,\n type: record.type,\n status: record.status,\n carrier: record.carrier ?? null,\n trackingNumber: record.trackingNumber ?? null,\n trackingUrl: record.trackingUrl ?? null,\n downloadUrl: record.downloadUrl ?? null,\n downloadExpiresAt: record.downloadExpiresAt\n ? new Date(record.downloadExpiresAt)\n : null,\n maxDownloads: record.maxDownloads ?? null,\n downloadCount: record.downloadCount ?? 0,\n entityType: record.entityType ?? null,\n entityId: record.entityId ?? null,\n grantedAt: record.grantedAt ? new Date(record.grantedAt) : null,\n expiresAt: record.expiresAt ? new Date(record.expiresAt) : null,\n isActive: record.isActive ?? true,\n customerId: record.customerId ?? null,\n },\n ctx,\n );\n\n // Create a fulfillment line item linking this fulfillment to the order line item\n for (const li of record.lineItems) {\n await this.deps.repository.createLineItem(\n {\n fulfillmentId: created.id,\n orderLineItemId: li.id,\n quantity: li.quantity,\n },\n ctx,\n );\n }\n\n }\n\n return Ok(undefined);\n }\n\n async getByOrderId(\n orderId: string,\n ctx?: TxContext,\n ): Promise<Result<FulfillmentRecord[]>> {\n const dbRecords = await this.deps.repository.findByOrderId(orderId, ctx);\n\n // Hydrate each record with its associated line items\n const records: FulfillmentRecord[] = [];\n for (const dbRecord of dbRecords) {\n const fulfillmentLineItems =\n await this.deps.repository.findLineItemsByFulfillmentId(\n dbRecord.id,\n ctx,\n );\n records.push(toServiceRecord(dbRecord, fulfillmentLineItems));\n }\n\n return Ok(records);\n }\n\n async updateTracking(\n input: {\n fulfillmentId: string;\n carrier?: string;\n trackingNumber?: string;\n trackingUrl?: string;\n status?: string;\n },\n ctx?: TxContext,\n ): Promise<Result<void>> {\n const existing = await this.deps.repository.findById(\n input.fulfillmentId,\n ctx,\n );\n if (!existing) {\n return Err(new CommerceNotFoundError(\"Fulfillment record not found.\"));\n }\n\n const updateData: Record<string, unknown> = {};\n if (input.carrier !== undefined) updateData.carrier = input.carrier;\n if (input.trackingNumber !== undefined)\n updateData.trackingNumber = input.trackingNumber;\n if (input.trackingUrl !== undefined)\n updateData.trackingUrl = input.trackingUrl;\n if (input.status !== undefined) updateData.status = input.status;\n if (input.status === \"shipped\") updateData.shippedAt = new Date();\n if (input.status === \"delivered\") updateData.deliveredAt = new Date();\n\n await this.deps.repository.update(input.fulfillmentId, updateData, ctx);\n return Ok(undefined);\n }\n\n async getDownloadUrl(\n orderId: string,\n lineItemId: string,\n userId: string,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<{ url: string; remaining: number; expiresAt: string }>> {\n const dbRecords = await this.deps.repository.findByOrderId(orderId, ctx);\n\n let matchedRecord: (typeof dbRecords)[number] | undefined;\n for (const dbRecord of dbRecords) {\n if (dbRecord.type !== \"digital-download\" && dbRecord.type !== \"digital\")\n continue;\n const fliItems = await this.deps.repository.findLineItemsByFulfillmentId(\n dbRecord.id,\n ctx,\n );\n if (fliItems.some((item) => item.orderLineItemId === lineItemId)) {\n matchedRecord = dbRecord;\n break;\n }\n }\n\n if (!matchedRecord) {\n return Err(new CommerceNotFoundError(\"Digital download not found.\"));\n }\n\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const order = await this.deps.ordersRepository.findById(orgId, orderId, ctx);\n if (!order || order.customerId !== userId) {\n return Err(new CommerceNotFoundError(\"Order not found.\"));\n }\n\n if (!matchedRecord.downloadExpiresAt || !matchedRecord.downloadUrl) {\n return Err(new CommerceNotFoundError(\"Download metadata missing.\"));\n }\n\n if (new Date(matchedRecord.downloadExpiresAt).getTime() < Date.now()) {\n return Err(new CommerceNotFoundError(\"Download link expired.\"));\n }\n\n const updated = await this.deps.repository.incrementDownloadCount(\n matchedRecord.id,\n ctx,\n );\n const downloadCount =\n updated?.downloadCount ?? matchedRecord.downloadCount + 1;\n const remaining = Math.max(\n 0,\n (matchedRecord.maxDownloads ?? 5) - downloadCount,\n );\n\n return Ok({\n url: matchedRecord.downloadUrl,\n remaining,\n expiresAt: matchedRecord.downloadExpiresAt.toISOString(),\n });\n }\n\n async getDigitalAccess(\n userId: string,\n type = \"course\",\n ctx?: TxContext,\n ): Promise<\n Result<\n Array<{\n entityId: string;\n title: string;\n grantedAt: string;\n expiresAt: string | null;\n isActive: boolean;\n orderId: string;\n }>\n >\n > {\n const output: Array<{\n entityId: string;\n title: string;\n grantedAt: string;\n expiresAt: string | null;\n isActive: boolean;\n orderId: string;\n }> = [];\n\n // Find all fulfillments for this customer\n const dbRecords = await this.deps.repository.findByCustomerId(userId, ctx);\n\n for (const entry of dbRecords) {\n if (entry.type !== \"digital-access\" && entry.type !== \"access_grant\")\n continue;\n if (entry.entityType !== type) continue;\n if (!entry.entityId || !entry.grantedAt) continue;\n\n // Get the first fulfillment line item to extract the title\n const fliItems = await this.deps.repository.findLineItemsByFulfillmentId(\n entry.id,\n ctx,\n );\n let title = \"Untitled\";\n if (fliItems.length > 0) {\n const orderLineItem = await this.deps.ordersRepository.findLineItemById(\n fliItems[0]!.orderLineItemId,\n ctx,\n );\n if (orderLineItem) {\n title = orderLineItem.title;\n }\n }\n\n output.push({\n entityId: entry.entityId,\n title,\n grantedAt: entry.grantedAt.toISOString(),\n expiresAt: entry.expiresAt?.toISOString() ?? null,\n isActive: entry.isActive,\n orderId: entry.orderId,\n });\n }\n\n return Ok(output);\n }\n}\n\n/**\n * Maps a Drizzle FulfillmentRecord + its fulfillment line items back to\n * the service-layer FulfillmentRecord shape used by callers.\n */\nfunction toServiceRecord(\n dbRecord: Awaited<ReturnType<FulfillmentRepository[\"findById\"]>> & {},\n fulfillmentLineItems: Awaited<\n ReturnType<FulfillmentRepository[\"findLineItemsByFulfillmentId\"]>\n >,\n): FulfillmentRecord {\n return {\n id: dbRecord.id,\n orderId: dbRecord.orderId,\n type: dbRecord.type,\n status: dbRecord.status,\n lineItems: fulfillmentLineItems.map((fli) => ({\n id: fli.orderLineItemId,\n title: \"\", // Title is on the order line item; callers should join if needed\n quantity: fli.quantity,\n })),\n ...(dbRecord.carrier != null ? { carrier: dbRecord.carrier } : {}),\n ...(dbRecord.trackingNumber != null\n ? { trackingNumber: dbRecord.trackingNumber }\n : {}),\n ...(dbRecord.trackingUrl != null\n ? { trackingUrl: dbRecord.trackingUrl }\n : {}),\n ...(dbRecord.estimatedDelivery != null\n ? { estimatedDelivery: dbRecord.estimatedDelivery.toISOString() }\n : {}),\n ...(dbRecord.shippedAt != null\n ? { shippedAt: dbRecord.shippedAt.toISOString() }\n : {}),\n ...(dbRecord.deliveredAt != null\n ? { deliveredAt: dbRecord.deliveredAt.toISOString() }\n : {}),\n ...(dbRecord.downloadUrl != null\n ? { downloadUrl: dbRecord.downloadUrl }\n : {}),\n ...(dbRecord.downloadExpiresAt != null\n ? { downloadExpiresAt: dbRecord.downloadExpiresAt.toISOString() }\n : {}),\n ...(dbRecord.maxDownloads != null\n ? { maxDownloads: dbRecord.maxDownloads }\n : {}),\n downloadCount: dbRecord.downloadCount,\n ...(dbRecord.customerId != null ? { customerId: dbRecord.customerId } : {}),\n ...(dbRecord.entityType != null ? { entityType: dbRecord.entityType } : {}),\n ...(dbRecord.entityId != null ? { entityId: dbRecord.entityId } : {}),\n ...(dbRecord.grantedAt != null\n ? { grantedAt: dbRecord.grantedAt.toISOString() }\n : {}),\n ...(dbRecord.expiresAt != null\n ? { expiresAt: dbRecord.expiresAt.toISOString() }\n : {}),\n isActive: dbRecord.isActive,\n };\n}\n",
|
|
108
|
+
"import { resolveOrgId } from \"../../auth/org\";\nimport type { Actor } from \"../../auth/types\";\nimport { CommerceNotFoundError } from \"../../kernel/errors\";\nimport { Err, Ok, type Result } from \"../../kernel/result\";\nimport type { TxContext } from \"../../kernel/database/tx-context\";\nimport type {\n CustomersRepository,\n Customer,\n CustomerAddress,\n CustomerAddressInsert,\n} from \"./repository\";\n\ninterface CustomerServiceDeps {\n repository: CustomersRepository;\n}\n\nexport class CustomerService {\n private readonly repo: CustomersRepository;\n\n constructor(private deps: CustomerServiceDeps) {\n this.repo = deps.repository;\n }\n\n private async getOrCreateByUserId(\n orgId: string,\n userId: string,\n ctx?: TxContext,\n ): Promise<Customer> {\n const existing = await this.repo.findByUserId(orgId, userId, ctx);\n if (existing) {\n return existing;\n }\n\n const customer = await this.repo.create(\n {\n organizationId: orgId,\n userId,\n metadata: {},\n },\n ctx,\n );\n\n return customer;\n }\n\n async getById(\n id: string,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Customer>> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const customer = await this.repo.findById(orgId, id, ctx);\n if (!customer) return Err(new CommerceNotFoundError(\"Customer not found.\"));\n return Ok(customer);\n }\n\n async getByUserId(\n userId: string,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Customer>> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const customer = await this.getOrCreateByUserId(orgId, userId, ctx);\n return Ok(customer);\n }\n\n async updateByUserId(\n userId: string,\n updates: Partial<\n Omit<Customer, \"id\" | \"userId\" | \"createdAt\" | \"updatedAt\">\n >,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Customer>> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const customer = await this.getOrCreateByUserId(orgId, userId, ctx);\n\n const updated = await this.repo.update(customer.id, updates, ctx);\n if (!updated) {\n return Err(new CommerceNotFoundError(\"Customer not found.\"));\n }\n\n return Ok(updated);\n }\n\n async getAddresses(\n userId: string,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CustomerAddress[]>> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const customer = await this.getOrCreateByUserId(orgId, userId, ctx);\n const addresses = await this.repo.findAddressesByCustomerId(\n customer.id,\n ctx,\n );\n return Ok(addresses);\n }\n\n async addAddress(\n userId: string,\n input: Omit<CustomerAddressInsert, \"id\" | \"customerId\">,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<CustomerAddress>> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const customer = await this.getOrCreateByUserId(orgId, userId, ctx);\n\n // If new address is default, unset other defaults of same type\n if (input.isDefault) {\n const addresses = await this.repo.findAddressesByCustomerId(\n customer.id,\n ctx,\n );\n for (const addr of addresses) {\n if (addr.type === input.type && addr.isDefault) {\n await this.repo.updateAddress(addr.id, { isDefault: false }, ctx);\n }\n }\n }\n\n const address = await this.repo.createAddress(\n {\n ...input,\n customerId: customer.id,\n },\n ctx,\n );\n\n return Ok(address);\n }\n\n async deleteAddress(\n userId: string,\n addressId: string,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<void>> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const customer = await this.getOrCreateByUserId(orgId, userId, ctx);\n const addresses = await this.repo.findAddressesByCustomerId(\n customer.id,\n ctx,\n );\n\n const addressExists = addresses.some((addr) => addr.id === addressId);\n if (!addressExists) {\n return Err(new CommerceNotFoundError(\"Address not found.\"));\n }\n\n await this.repo.deleteAddress(addressId, ctx);\n return Ok(undefined);\n }\n\n async findPOSOperatorByPin(\n hashedPin: string,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<{ id: string; name: string } | null> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const user = await this.repo.findByPosPin(orgId, hashedPin, ctx);\n if (!user) return null;\n return {\n id: user.userId,\n name:\n [user.firstName, user.lastName].filter(Boolean).join(\" \") ||\n user.email ||\n \"POS Operator\",\n };\n }\n}\n",
|
|
109
|
+
"import { resolveOrgId } from \"../../auth/org\";\nimport type { Actor } from \"../../auth/types\";\nimport { CommerceNotFoundError, CommerceValidationError } from \"../../kernel/errors\";\nimport { Err, Ok, type Result } from \"../../kernel/result\";\nimport type { TxContext } from \"../../kernel/database/tx-context\";\nimport type { WebhooksRepository, WebhookEndpoint } from \"./repository\";\n\n/**\n * Checks whether a URL points to a private/internal IP address.\n * Blocks: loopback (127.x), link-local (169.254.x), private (10.x, 172.16-31.x, 192.168.x),\n * cloud metadata (169.254.169.254, metadata.google.internal), and localhost.\n */\nfunction isPrivateUrl(urlStr: string): boolean {\n try {\n const parsed = new URL(urlStr);\n // Strip IPv6 brackets: URL.hostname returns \"[::1]\" not \"::1\"\n const hostname = parsed.hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n\n // Loopback (IPv4 + IPv6)\n if (hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"::1\") return true;\n if (hostname.endsWith(\".localhost\")) return true;\n\n // IPv6 loopback and link-local patterns\n if (hostname.startsWith(\"::ffff:\")) return true; // IPv6-mapped IPv4 (e.g., ::ffff:127.0.0.1)\n if (hostname.startsWith(\"fe80:\")) return true; // IPv6 link-local\n if (hostname === \"::\") return true; // Unspecified address\n\n // Cloud metadata endpoints\n if (hostname === \"169.254.169.254\") return true;\n if (hostname === \"metadata.google.internal\") return true;\n\n // Private IP ranges (RFC 1918 + link-local)\n const parts = hostname.split(\".\").map(Number);\n if (parts.length === 4 && parts.every((n) => !isNaN(n))) {\n const [a, b] = parts;\n if (a === 10) return true;\n if (a === 172 && b !== undefined && b >= 16 && b <= 31) return true;\n if (a === 192 && b === 168) return true;\n if (a === 169 && b === 254) return true;\n if (a === 127) return true; // Full 127.0.0.0/8 range\n if (a === 0) return true;\n }\n\n return false;\n } catch {\n return true; // Invalid URLs are blocked\n }\n}\n\ninterface WebhookServiceDeps {\n repository: WebhooksRepository;\n}\n\nexport class WebhookService {\n private readonly repo: WebhooksRepository;\n\n constructor(private deps: WebhookServiceDeps) {\n this.repo = deps.repository;\n }\n\n async createEndpoint(\n input: {\n url: string;\n secret: string;\n events: string[];\n metadata?: Record<string, unknown>;\n },\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<WebhookEndpoint>> {\n if (isPrivateUrl(input.url)) {\n return Err(\n new CommerceValidationError(\n \"Webhook URL must not point to a private or internal address.\",\n ),\n );\n }\n\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n\n const endpoint = await this.repo.createEndpoint(\n {\n organizationId: orgId,\n url: input.url,\n secret: input.secret,\n events: input.events,\n isActive: true,\n metadata: input.metadata ?? {},\n },\n ctx,\n );\n return Ok(endpoint);\n }\n\n async listEndpoints(ctx?: TxContext): Promise<Result<WebhookEndpoint[]>> {\n const endpoints = await this.repo.findAllEndpoints(ctx);\n return Ok(endpoints);\n }\n\n async deleteEndpoint(id: string, ctx?: TxContext): Promise<Result<void>> {\n const existing = await this.repo.findEndpointById(id, ctx);\n if (!existing) {\n return Err(new CommerceNotFoundError(\"Webhook endpoint not found.\"));\n }\n\n await this.repo.deleteEndpoint(id, ctx);\n return Ok(undefined);\n }\n\n async getEndpointsForEvent(\n eventName: string,\n ctx?: TxContext,\n ): Promise<Result<WebhookEndpoint[]>> {\n const endpoints = await this.repo.findEndpointsForEvent(eventName, ctx);\n return Ok(endpoints);\n }\n}\n",
|
|
110
|
+
"/**\n * AnalyticsService — thin delegation layer over AnalyticsAdapter.\n *\n * The service manages plugin model registration, custom schema loading,\n * and delegates all query execution to the configured adapter\n * (DrizzleAnalyticsAdapter — always on, built into core).\n */\n\nimport type { CommerceConfig } from \"../../config/types\";\nimport { CommerceValidationError } from \"../../kernel/errors\";\nimport { Err, Ok, type Result } from \"../../kernel/result\";\nimport type {\n AnalyticsAdapter,\n AnalyticsMeta,\n AnalyticsModel,\n AnalyticsModelDefinition,\n AnalyticsQueryParams,\n AnalyticsQueryResult,\n AnalyticsScope,\n} from \"./types\";\n\n// Re-export types for backwards compatibility\nexport type {\n AnalyticsTimeDimension,\n AnalyticsFilter,\n AnalyticsQueryParams,\n AnalyticsModelDefinition,\n AnalyticsMeta,\n} from \"./types\";\n\nexport interface AnalyticsServiceDeps {\n adapter: AnalyticsAdapter;\n config: CommerceConfig;\n}\n\nexport class AnalyticsService {\n private pluginModels: AnalyticsModelDefinition[] = [];\n private customSchemaModels: AnalyticsModelDefinition[] = [];\n private customModelsLoaded = false;\n\n constructor(private deps: AnalyticsServiceDeps) {}\n\n /**\n * Register a plugin-contributed analytics model.\n *\n * If the model includes a `table` field and structured measures/dimensions,\n * it is also registered as an AnalyticsModel on the adapter for SQL queries.\n * Otherwise, it appears in getMeta() but queries return zero-value rows.\n */\n registerModel(model: unknown): void {\n if (!model || typeof model !== \"object\") return;\n\n const raw = model as Record<string, unknown>;\n const name =\n typeof raw.name === \"string\"\n ? raw.name\n : `PluginModel_${this.pluginModels.length + 1}`;\n const measures = Array.isArray(raw.measures)\n ? raw.measures.filter((v): v is string => typeof v === \"string\")\n : [];\n const dimensions = Array.isArray(raw.dimensions)\n ? raw.dimensions.filter((v): v is string => typeof v === \"string\")\n : [];\n const segments = Array.isArray(raw.segments)\n ? raw.segments.filter((v): v is string => typeof v === \"string\")\n : [];\n\n this.pluginModels.push({\n name,\n source: \"plugin\",\n measures,\n dimensions,\n segments,\n raw: model,\n });\n\n // If the model provides a table + structured definitions, register on the adapter\n if (typeof raw.table === \"string\" && Array.isArray(raw.measures)) {\n this.tryRegisterModel(name, raw);\n }\n }\n\n /**\n * Query analytics with scope-based filtering.\n * Scope is REQUIRED — use buildAnalyticsScope(actor) to construct it.\n */\n async query(params: AnalyticsQueryParams, scope: AnalyticsScope): Promise<Result<AnalyticsQueryResult>> {\n return this.deps.adapter.query(params, scope);\n }\n\n async getDashboard(name: string, scope: AnalyticsScope): Promise<Result<AnalyticsQueryResult>> {\n const normalized = name.trim().toLowerCase();\n\n if (normalized === \"revenue\" || normalized === \"revenue-overview\") {\n return this.query({\n measures: [\"Orders.revenue\", \"Orders.count\"],\n timeDimensions: [{\n dimension: \"Orders.placedAt\",\n granularity: \"month\",\n dateRange: \"this month\",\n }],\n order: { \"Orders.placedAt\": \"asc\" },\n }, scope);\n }\n\n if (normalized === \"inventory\" || normalized === \"inventory-health\") {\n return this.query({\n measures: [\"Inventory.totalAvailable\", \"Inventory.lowStockCount\"],\n dimensions: [\"Inventory.warehouseId\"],\n order: { \"Inventory.totalAvailable\": \"desc\" },\n }, scope);\n }\n\n return Err(\n new CommerceValidationError(`Unknown analytics dashboard: ${name}`),\n );\n }\n\n async getMeta(): Promise<Result<AnalyticsMeta>> {\n await this.ensureCustomSchemaModelsLoaded();\n\n // Meta returns model definitions, not data — always use admin scope\n const adapterMeta = await this.deps.adapter.getMeta({ role: \"admin\" });\n if (!adapterMeta.ok) return adapterMeta;\n\n // Merge with plugin and custom schema models\n const allModels = [\n ...adapterMeta.value.models,\n ...this.pluginModels,\n ...this.customSchemaModels,\n ];\n\n return Ok({\n models: allModels,\n measures: allModels.flatMap((m) => m.measures),\n dimensions: allModels.flatMap((m) => m.dimensions),\n segments: allModels.flatMap((m) => m.segments ?? []),\n });\n }\n\n async meta(): Promise<Result<{ measures: string[]; dimensions: string[]; segments: string[] }>> {\n const meta = await this.getMeta();\n if (!meta.ok) return meta;\n return Ok({\n measures: meta.value.measures,\n dimensions: meta.value.dimensions,\n segments: meta.value.segments,\n });\n }\n\n // ─── Private ─────────────────────────────────────────────────────────────\n\n private tryRegisterModel(name: string, raw: Record<string, unknown>): void {\n try {\n const table = raw.table as string;\n const measuresArray = raw.measures as Array<Record<string, unknown>>;\n const dimensionsArray = (raw.dimensions ?? []) as Array<Record<string, unknown>>;\n\n const modelDef: AnalyticsModel = {\n name,\n table,\n measures: {},\n dimensions: {},\n };\n\n for (const m of measuresArray) {\n if (typeof m === \"string\") continue;\n if (typeof m.name === \"string\" && typeof m.type === \"string\") {\n modelDef.measures[m.name] = {\n type: m.type as AnalyticsModel[\"measures\"][string][\"type\"],\n sql: typeof m.sql === \"string\" ? m.sql : undefined,\n filter: typeof m.filter === \"string\" ? m.filter : undefined,\n };\n }\n }\n\n for (const d of dimensionsArray) {\n if (typeof d === \"string\") continue;\n if (typeof d.name === \"string\" && typeof d.sql === \"string\") {\n modelDef.dimensions[d.name] = {\n sql: d.sql,\n type: (typeof d.type === \"string\" ? d.type : \"string\") as AnalyticsModel[\"dimensions\"][string][\"type\"],\n };\n }\n }\n\n if (Object.keys(modelDef.measures).length > 0) {\n this.deps.adapter.registerModel(modelDef);\n }\n } catch {\n // Silently skip malformed plugin models\n }\n }\n\n private async ensureCustomSchemaModelsLoaded(): Promise<void> {\n if (this.customModelsLoaded) return;\n this.customModelsLoaded = true;\n\n const customSchemaPath = this.deps.config.analytics?.customSchemaPath;\n if (!customSchemaPath) return;\n\n try {\n const fs = await import(\"node:fs/promises\");\n const path = await import(\"node:path\");\n const entries = await fs.readdir(customSchemaPath);\n\n for (const entry of entries) {\n if (!entry.endsWith(\".js\")) continue;\n const filePath = path.join(customSchemaPath, entry);\n const content = await fs.readFile(filePath, \"utf8\");\n\n const nameMatch = content.match(/cube\\s*\\(\\s*[\"'`]([\\w-]+)[\"'`]/);\n const name = nameMatch?.[1] ?? entry.replace(/\\.js$/, \"\");\n\n const measures = [\n ...content.matchAll(/measures\\s*:\\s*{([\\s\\S]*?)}\\s*,/g),\n ].flatMap((match) => {\n const block = match[1] ?? \"\";\n return [...block.matchAll(/([A-Za-z_][A-Za-z0-9_]*)\\s*:\\s*{/g)].map(\n (x) => `${name}.${x[1]}`,\n );\n });\n\n const dimensions = [\n ...content.matchAll(/dimensions\\s*:\\s*{([\\s\\S]*?)}\\s*,/g),\n ].flatMap((match) => {\n const block = match[1] ?? \"\";\n return [...block.matchAll(/([A-Za-z_][A-Za-z0-9_]*)\\s*:\\s*{/g)].map(\n (x) => `${name}.${x[1]}`,\n );\n });\n\n this.customSchemaModels.push({\n name,\n source: \"custom-schema\",\n measures,\n dimensions,\n raw: { path: filePath },\n });\n }\n } catch {\n // Optional extension path: ignore file-system issues\n }\n }\n}\n",
|
|
111
|
+
"import { sql, type SQL } from \"drizzle-orm\";\nimport type { DrizzleDatabase } from \"../../kernel/database/drizzle-db\";\nimport { CommerceValidationError } from \"../../kernel/errors\";\nimport { Err, Ok, type Result } from \"../../kernel/result\";\nimport type {\n AnalyticsAdapter,\n AnalyticsFilter,\n AnalyticsMeta,\n AnalyticsModel,\n AnalyticsModelDefinition,\n AnalyticsQueryParams,\n AnalyticsQueryResult,\n AnalyticsScope,\n AnalyticsTimeDimension,\n} from \"./types\";\n\n// ─── Date Range Parsing ──────────────────────────────────────────────────────\n\nfunction parseDateRange(range: AnalyticsTimeDimension[\"dateRange\"]): [Date, Date] | null {\n if (Array.isArray(range)) {\n const start = new Date(range[0]!);\n const end = new Date(range[1]!);\n if (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime())) return null;\n return [start, end];\n }\n if (typeof range !== \"string\") return null;\n\n const now = new Date();\n const lower = range.toLowerCase();\n\n if (lower === \"last month\") {\n return [\n new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() - 1, 1)),\n new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 0, 23, 59, 59, 999)),\n ];\n }\n if (lower === \"this month\") {\n return [\n new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1)),\n new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 0, 23, 59, 59, 999)),\n ];\n }\n\n const qMatch = range.match(/^Q([1-4])\\s+(\\d{4})$/i);\n if (qMatch) {\n const quarter = Number(qMatch[1]);\n const year = Number(qMatch[2]);\n const monthStart = (quarter - 1) * 3;\n return [\n new Date(Date.UTC(year, monthStart, 1)),\n new Date(Date.UTC(year, monthStart + 3, 0, 23, 59, 59, 999)),\n ];\n }\n\n return null;\n}\n\nfunction pickCube(params: AnalyticsQueryParams): string {\n const first = [\n ...(params.measures ?? []),\n ...(params.dimensions ?? []),\n ...(params.timeDimensions ?? []).map((td) => td.dimension),\n ...(params.filters ?? []).map((f) => f.member),\n ][0];\n if (!first) return \"Orders\";\n return first.split(\".\")[0] ?? \"Orders\";\n}\n\n// ─── Granularity to TO_CHAR format ───────────────────────────────────────────\n\nconst GRANULARITY_FORMAT: Record<string, string> = {\n day: \"YYYY-MM-DD\",\n week: \"IYYY-\\\"W\\\"IW\",\n month: \"YYYY-MM\",\n year: \"YYYY\",\n};\n\n// ─── SQL Compilation Helpers ─────────────────────────────────────────────────\n\nfunction compileMeasure(cube: AnalyticsModel, measureName: string): SQL {\n const shortName = measureName.split(\".\")[1]!;\n const def = cube.measures[shortName];\n if (!def) return sql`0`;\n\n switch (def.type) {\n case \"count\":\n if (def.filter) {\n return sql.raw(`COUNT(CASE WHEN ${def.filter} THEN 1 END)`);\n }\n return sql`COUNT(*)`;\n case \"sum\":\n return sql.raw(`COALESCE(SUM(${def.sql!}), 0)`);\n case \"avg\":\n return sql.raw(`COALESCE(ROUND(AVG(${def.sql!})), 0)`);\n case \"min\":\n return sql.raw(`MIN(${def.sql!})`);\n case \"max\":\n return sql.raw(`MAX(${def.sql!})`);\n case \"countDistinct\":\n return sql.raw(`COUNT(DISTINCT ${def.sql!})`);\n }\n}\n\nfunction compileTimeDimensionSelect(cube: AnalyticsModel, td: AnalyticsTimeDimension): SQL {\n const shortName = td.dimension.split(\".\")[1]!;\n const dimDef = cube.dimensions[shortName];\n if (!dimDef) return sql`NULL`;\n\n const gran = td.granularity ?? \"day\";\n // Validate granularity against whitelist to prevent SQL injection\n if (!(gran in GRANULARITY_FORMAT)) {\n return sql`NULL`;\n }\n const format = GRANULARITY_FORMAT[gran]!;\n return sql.raw(`TO_CHAR(DATE_TRUNC('${gran}', ${dimDef.sql}), '${format}')`);\n}\n\nfunction compileFilter(cube: AnalyticsModel, filter: AnalyticsFilter): SQL | null {\n const shortName = filter.member.split(\".\")[1]!;\n const dimDef = cube.dimensions[shortName];\n if (!dimDef) return null;\n\n const col = dimDef.sql;\n const values = filter.values ?? [];\n if (values.length === 0) return null;\n\n switch (filter.operator) {\n case \"equals\":\n return sql`${sql.raw(col)} = ${values[0]!}`;\n case \"notEquals\":\n return sql`${sql.raw(col)} != ${values[0]!}`;\n case \"contains\":\n return sql`${sql.raw(col)} ILIKE ${\"%\" + values[0]! + \"%\"}`;\n case \"in\":\n return sql`${sql.raw(col)} IN (${sql.join(values.map((v) => sql`${v}`), sql`, `)})`;\n case \"notIn\":\n return sql`${sql.raw(col)} NOT IN (${sql.join(values.map((v) => sql`${v}`), sql`, `)})`;\n case \"gt\":\n return sql`${sql.raw(col)} > ${Number(values[0]!)}`;\n case \"gte\":\n return sql`${sql.raw(col)} >= ${Number(values[0]!)}`;\n case \"lt\":\n return sql`${sql.raw(col)} < ${Number(values[0]!)}`;\n case \"lte\":\n return sql`${sql.raw(col)} <= ${Number(values[0]!)}`;\n case \"beforeDate\":\n return sql`${sql.raw(col)} <= ${values[0]!}::timestamptz`;\n case \"afterDate\":\n return sql`${sql.raw(col)} >= ${values[0]!}::timestamptz`;\n case \"inDateRange\":\n if (values.length >= 2) {\n return sql`${sql.raw(col)} BETWEEN ${values[0]!}::timestamptz AND ${values[1]!}::timestamptz`;\n }\n return null;\n }\n}\n\n// ─── DrizzleAnalyticsAdapter ─────────────────────────────────────────────────\n\nexport class DrizzleAnalyticsAdapter implements AnalyticsAdapter {\n private models = new Map<string, AnalyticsModel>();\n\n constructor(private db: DrizzleDatabase) {}\n\n registerModel(model: AnalyticsModel): void {\n this.models.set(model.name, model);\n }\n\n async query(params: AnalyticsQueryParams, scope: AnalyticsScope): Promise<Result<AnalyticsQueryResult>> {\n if (!params.measures || params.measures.length === 0) {\n return Err(new CommerceValidationError(\"analytics.query requires at least one measure.\"));\n }\n\n const cubeName = pickCube(params);\n\n // Validate all members are from the same cube\n const allMembers = [\n ...params.measures,\n ...(params.dimensions ?? []),\n ...(params.timeDimensions ?? []).map((td) => td.dimension),\n ];\n const wrongCube = allMembers.find((m) => m.split(\".\")[0] !== cubeName);\n if (wrongCube) {\n return Err(new CommerceValidationError(\n `analytics.query currently requires measures from a single cube. Found \"${wrongCube}\" in \"${cubeName}\" query.`,\n ));\n }\n\n const cube = this.models.get(cubeName);\n if (!cube) {\n const available = [...this.models.keys()].join(\", \");\n return Err(new CommerceValidationError(\n `Unknown analytics cube: \"${cubeName}\". Available cubes: ${available}`,\n ));\n }\n\n // Validate that requested measures exist in the cube\n for (const measure of params.measures) {\n const shortName = measure.split(\".\")[1];\n if (shortName && !cube.measures[shortName]) {\n const available = Object.keys(cube.measures).map((m) => `${cubeName}.${m}`).join(\", \");\n return Err(new CommerceValidationError(\n `Unknown measure: \"${measure}\". Available measures for ${cubeName}: ${available}`,\n ));\n }\n }\n\n // Validate that requested dimensions exist in the cube\n for (const dim of params.dimensions ?? []) {\n const shortName = dim.split(\".\")[1];\n if (shortName && !cube.dimensions[shortName]) {\n const available = Object.keys(cube.dimensions).map((d) => `${cubeName}.${d}`).join(\", \");\n return Err(new CommerceValidationError(\n `Unknown dimension: \"${dim}\". Available dimensions for ${cubeName}: ${available}`,\n ));\n }\n }\n\n try {\n const rows = await this.executeQuery(cube, params, scope);\n return Ok({\n query: params,\n rows,\n source: cubeName,\n });\n } catch (error) {\n return Err(new CommerceValidationError(\n `Analytics query failed: ${error instanceof Error ? error.message : String(error)}`,\n ));\n }\n }\n\n async getMeta(_scope: AnalyticsScope): Promise<Result<AnalyticsMeta>> {\n const models: AnalyticsModelDefinition[] = [];\n\n for (const cube of this.models.values()) {\n models.push({\n name: cube.name,\n source: \"builtin\",\n measures: Object.keys(cube.measures).map((m) => `${cube.name}.${m}`),\n dimensions: Object.keys(cube.dimensions).map((d) => `${cube.name}.${d}`),\n segments: cube.segments\n ? Object.keys(cube.segments).map((s) => `${cube.name}.${s}`)\n : [],\n });\n }\n\n return Ok({\n models,\n measures: models.flatMap((m) => m.measures),\n dimensions: models.flatMap((m) => m.dimensions),\n segments: models.flatMap((m) => m.segments ?? []),\n });\n }\n\n // ─── SQL Query Builder ───────────────────────────────────────────────────\n\n private async executeQuery(\n cube: AnalyticsModel,\n params: AnalyticsQueryParams,\n scope: AnalyticsScope,\n ): Promise<Record<string, unknown>[]> {\n const selectParts: SQL[] = [];\n const groupByParts: SQL[] = [];\n const whereParts: SQL[] = [];\n\n // ── Scope-based filtering (always applied) ───────────────────────\n //\n // Security model (hardened by default):\n // admin/staff → no filter (full access)\n // vendor/customer → MUST have a matching scopeRule, or blocked\n // public → always blocked\n //\n // Scope is REQUIRED — there is no unscoped code path.\n {\n if (scope.role === \"public\") {\n whereParts.push(sql.raw(\"1 = 0\"));\n } else if (scope.role !== \"admin\" && scope.role !== \"staff\") {\n // Vendor or customer: look for a matching scope rule\n let scopeApplied = false;\n\n if (cube.scopeRules) {\n for (const rule of cube.scopeRules) {\n if (rule.role === scope.role) {\n // Use parameterized SQL for scope values to prevent injection.\n // The filter template uses :vendorId / :customerId placeholders.\n // We split the filter on placeholders and build a parameterized\n // sql`` template instead of using sql.raw() with string interpolation.\n let filterSql = rule.filter;\n if (scope.vendorId && filterSql.includes(\":vendorId\")) {\n // Replace placeholder with parameterized value\n const parts = filterSql.split(\":vendorId\");\n const fragments = parts.map((part, i) =>\n i < parts.length - 1\n ? sql`${sql.raw(part)}${scope.vendorId!}`\n : sql.raw(part),\n );\n whereParts.push(sql.join(fragments, sql``));\n scopeApplied = true;\n continue;\n }\n if (scope.customerId && filterSql.includes(\":customerId\")) {\n const parts = filterSql.split(\":customerId\");\n const fragments = parts.map((part, i) =>\n i < parts.length - 1\n ? sql`${sql.raw(part)}${scope.customerId!}`\n : sql.raw(part),\n );\n whereParts.push(sql.join(fragments, sql``));\n scopeApplied = true;\n continue;\n }\n // No placeholder found — use raw (trusted scope rule SQL)\n whereParts.push(sql.raw(filterSql));\n scopeApplied = true;\n }\n }\n }\n\n // Deny-by-default: if no scope rule matched, block access\n if (!scopeApplied) {\n whereParts.push(sql.raw(\"1 = 0\"));\n }\n }\n // admin/staff: no filter applied — full access\n }\n\n // Dimensions → SELECT + GROUP BY\n for (const dim of params.dimensions ?? []) {\n const shortName = dim.split(\".\")[1]!;\n const dimDef = cube.dimensions[shortName];\n if (!dimDef) continue;\n selectParts.push(sql.raw(`${dimDef.sql} AS \"${dim}\"`));\n groupByParts.push(sql.raw(dimDef.sql));\n }\n\n // Time dimensions → SELECT + GROUP BY + WHERE (dateRange)\n for (const td of params.timeDimensions ?? []) {\n const selectExpr = compileTimeDimensionSelect(cube, td);\n selectParts.push(sql`${selectExpr} AS ${sql.raw(`\"${td.dimension}\"`)}`);\n groupByParts.push(selectExpr);\n\n // Date range filter\n if (td.dateRange) {\n const range = parseDateRange(td.dateRange);\n if (range) {\n const shortName = td.dimension.split(\".\")[1]!;\n const dimDef = cube.dimensions[shortName];\n if (dimDef) {\n whereParts.push(\n sql`${sql.raw(dimDef.sql)} >= ${range[0].toISOString()}::timestamptz AND ${sql.raw(dimDef.sql)} < ${range[1].toISOString()}::timestamptz`,\n );\n }\n }\n }\n }\n\n // Measures → SELECT\n for (const measure of params.measures) {\n selectParts.push(sql`${compileMeasure(cube, measure)} AS ${sql.raw(`\"${measure}\"`)}`);\n }\n\n // If no select parts (shouldn't happen with validation), bail\n if (selectParts.length === 0) {\n return [];\n }\n\n // FROM + JOINs\n let fromFragment = sql.raw(cube.table);\n for (const join of cube.joins ?? []) {\n const joinType = join.type === \"inner\" ? \"INNER JOIN\" : \"LEFT JOIN\";\n fromFragment = sql`${fromFragment} ${sql.raw(joinType)} ${sql.raw(join.table)} ON ${sql.raw(join.on)}`;\n }\n\n // Filters → WHERE\n for (const filter of params.filters ?? []) {\n const compiled = compileFilter(cube, filter);\n if (compiled) whereParts.push(compiled);\n }\n\n // ORDER BY — validate member names against the cube's registered measures/dimensions\n const validMeasures = new Set(Object.keys(cube.measures).map((m) => `${cube.name}.${m}`));\n const validDimensions = new Set(Object.keys(cube.dimensions).map((d) => `${cube.name}.${d}`));\n const orderParts: SQL[] = [];\n for (const [member, dir] of Object.entries(params.order ?? {})) {\n if (!validMeasures.has(member) && !validDimensions.has(member)) {\n continue; // skip unknown members to prevent SQL injection via sql.raw()\n }\n const normalizedDir = dir.toUpperCase() === \"DESC\" ? \"DESC\" : \"ASC\";\n orderParts.push(sql.raw(`\"${member}\" ${normalizedDir}`));\n }\n\n // LIMIT\n const limit = Math.max(1, Math.min(params.limit ?? 100, 1000));\n\n // Assemble the full query\n const selectClause = sql.join(selectParts, sql`, `);\n const whereClause = whereParts.length > 0\n ? sql`WHERE ${sql.join(whereParts, sql` AND `)}`\n : sql``;\n const groupByClause = groupByParts.length > 0\n ? sql`GROUP BY ${sql.join(groupByParts, sql`, `)}`\n : sql``;\n const orderClause = orderParts.length > 0\n ? sql`ORDER BY ${sql.join(orderParts, sql`, `)}`\n : sql``;\n\n const fullQuery = sql`SELECT ${selectClause} FROM ${fromFragment} ${whereClause} ${groupByClause} ${orderClause} LIMIT ${limit}`;\n\n const result = await this.db.execute(fullQuery);\n\n // Map results: convert bigint to number, preserve column aliases\n // db.execute() returns different shapes per driver — normalize to array of rows\n const rawRows: Record<string, unknown>[] = Array.isArray(result)\n ? result\n : (result as { rows?: Record<string, unknown>[] }).rows ?? [];\n\n return rawRows.map((row: Record<string, unknown>) => {\n const mapped: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(row)) {\n mapped[key] = typeof value === \"bigint\" ? Number(value) : value;\n }\n return mapped;\n });\n }\n}\n",
|
|
112
|
+
"import type { AnalyticsModel } from \"./types\";\n\n/**\n * Built-in analytics model definitions for the 4 core tables.\n *\n * Each model maps semantic names (e.g., \"Orders.revenue\") to PostgreSQL\n * columns and aggregations. The DrizzleAnalyticsAdapter compiles these\n * into parameterized SQL queries at runtime.\n */\n\nexport const ORDERS_MODEL: AnalyticsModel = {\n name: \"Orders\",\n table: \"orders\",\n scopeRules: [\n { role: \"vendor\", filter: \"id IN (SELECT order_id FROM marketplace_vendor_sub_orders WHERE vendor_id = :vendorId)\" },\n { role: \"customer\", filter: \"customer_id = :customerId\" },\n ],\n measures: {\n count: { type: \"count\" },\n revenue: { sql: \"grand_total\", type: \"sum\" },\n averageOrderValue: { sql: \"grand_total\", type: \"avg\" },\n subtotalRevenue: { sql: \"subtotal\", type: \"sum\" },\n taxCollected: { sql: \"tax_total\", type: \"sum\" },\n shippingRevenue: { sql: \"shipping_total\", type: \"sum\" },\n discountsGiven: { sql: \"discount_total\", type: \"sum\" },\n uniqueCustomers: { sql: \"customer_id\", type: \"countDistinct\" },\n },\n dimensions: {\n id: { sql: \"id\", type: \"string\" },\n orderNumber: { sql: \"order_number\", type: \"string\" },\n status: { sql: \"status\", type: \"string\" },\n currency: { sql: \"currency\", type: \"string\" },\n placedAt: { sql: \"placed_at\", type: \"time\" },\n },\n};\n\nexport const ORDER_LINE_ITEMS_MODEL: AnalyticsModel = {\n name: \"OrderLineItems\",\n table: \"order_line_items\",\n scopeRules: [\n { role: \"vendor\", filter: \"order_id IN (SELECT order_id FROM marketplace_vendor_sub_orders WHERE vendor_id = :vendorId)\" },\n { role: \"customer\", filter: \"order_id IN (SELECT id FROM orders WHERE customer_id = :customerId)\" },\n ],\n joins: [\n {\n table: \"orders\",\n type: \"left\",\n on: \"order_line_items.order_id = orders.id\",\n },\n ],\n measures: {\n count: { type: \"count\" },\n itemsSold: { sql: \"order_line_items.quantity\", type: \"sum\" },\n lineItemRevenue: { sql: \"order_line_items.total_price\", type: \"sum\" },\n averageUnitPrice: { sql: \"order_line_items.unit_price\", type: \"avg\" },\n },\n dimensions: {\n id: { sql: \"order_line_items.id\", type: \"string\" },\n entityType: { sql: \"order_line_items.entity_type\", type: \"string\" },\n sku: { sql: \"order_line_items.sku\", type: \"string\" },\n title: { sql: \"order_line_items.title\", type: \"string\" },\n fulfillmentStatus: { sql: \"order_line_items.fulfillment_status\", type: \"string\" },\n },\n};\n\nexport const INVENTORY_MODEL: AnalyticsModel = {\n name: \"Inventory\",\n table: \"inventory_levels\",\n scopeRules: [\n { role: \"vendor\", filter: \"entity_id IN (SELECT entity_id FROM marketplace_vendor_entities WHERE vendor_id = :vendorId)\" },\n ],\n measures: {\n totalOnHand: { sql: \"quantity_on_hand\", type: \"sum\" },\n totalReserved: { sql: \"quantity_reserved\", type: \"sum\" },\n totalAvailable: { sql: \"(quantity_on_hand - quantity_reserved)\", type: \"sum\" },\n inventoryValue: { sql: \"(quantity_on_hand * COALESCE(unit_cost, 0))\", type: \"sum\" },\n lowStockCount: {\n type: \"count\",\n filter: \"reorder_threshold IS NOT NULL AND (quantity_on_hand - quantity_reserved) <= reorder_threshold\",\n },\n },\n dimensions: {\n entityId: { sql: \"entity_id\", type: \"string\" },\n warehouseId: { sql: \"warehouse_id\", type: \"string\" },\n lastRestockedAt: { sql: \"last_restocked_at\", type: \"time\" },\n },\n segments: {\n lowStock: {\n sql: \"reorder_threshold IS NOT NULL AND (quantity_on_hand - quantity_reserved) <= reorder_threshold\",\n },\n },\n};\n\nexport const CUSTOMERS_MODEL: AnalyticsModel = {\n name: \"Customers\",\n table: \"customers\",\n scopeRules: [\n { role: \"vendor\", filter: \"id IN (SELECT DISTINCT customer_id FROM orders WHERE id IN (SELECT order_id FROM marketplace_vendor_sub_orders WHERE vendor_id = :vendorId) AND customer_id IS NOT NULL)\" },\n { role: \"customer\", filter: \"id = :customerId\" },\n ],\n measures: {\n customerCount: { type: \"count\" },\n newCustomers: { type: \"count\" },\n returningCustomers: {\n type: \"count\",\n filter: \"(SELECT COUNT(*) FROM orders WHERE orders.customer_id = customers.id) > 1\",\n },\n },\n dimensions: {\n createdAt: { sql: \"created_at\", type: \"time\" },\n customerGroup: { sql: \"COALESCE(metadata->>'customerGroup', 'default')\", type: \"string\" },\n },\n segments: {\n returning: {\n sql: \"(SELECT COUNT(*) FROM orders WHERE orders.customer_id = customers.id) > 1\",\n },\n },\n};\n\nexport const BUILTIN_ANALYTICS_MODELS: AnalyticsModel[] = [\n ORDERS_MODEL,\n ORDER_LINE_ITEMS_MODEL,\n INVENTORY_MODEL,\n CUSTOMERS_MODEL,\n];\n",
|
|
113
|
+
"import { resolveOrgId } from \"../../auth/org\";\nimport type { Actor } from \"../../auth/types\";\nimport {\n CommerceNotFoundError,\n CommerceValidationError,\n} from \"../../kernel/errors\";\nimport { Err, Ok, type Result } from \"../../kernel/result\";\nimport type { TxContext } from \"../../kernel/database/tx-context\";\nimport type {\n PricingRepository,\n Price,\n PriceModifier,\n PriceInsert,\n PriceModifierInsert,\n} from \"./repository\";\nimport type { CatalogRepository } from \"../catalog/repository\";\n\n// Re-export PriceModifierType from schema for external use\nexport type PriceModifierType =\n | \"percentage_discount\"\n | \"fixed_discount\"\n | \"markup\"\n | \"override\";\n\ninterface PricingServiceDeps {\n repository: PricingRepository;\n catalogRepository: CatalogRepository;\n}\n\nexport interface PriceResolutionContext {\n entityId: string;\n variantId?: string;\n currency: string;\n quantity: number;\n customerId?: string;\n customerGroupIds?: string[];\n timestamp?: Date;\n}\n\nexport interface PriceBreakdownStep {\n label: string;\n amountBefore: number;\n delta: number;\n amountAfter: number;\n metadata?: Record<string, unknown>;\n}\n\nexport interface ResolvedPrice {\n baseAmount: number;\n finalAmount: number;\n currency: string;\n appliedModifiers: Array<{\n id: string;\n name: string;\n type: PriceModifierType;\n delta: number;\n value: number;\n priority: number;\n }>;\n breakdown: PriceBreakdownStep[];\n basePriceId: string;\n}\n\nexport type { SetBasePriceInput, CreatePriceModifierInput } from \"./schemas\";\nimport type { SetBasePriceInput, CreatePriceModifierInput } from \"./schemas\";\n\nfunction matchesQuantity(\n min: number | null | undefined,\n max: number | null | undefined,\n quantity: number,\n): boolean {\n if (min != null && quantity < min) return false;\n if (max != null && quantity > max) return false;\n return true;\n}\n\nfunction matchesWindow(\n validFrom: Date | null | undefined,\n validUntil: Date | null | undefined,\n timestamp: Date,\n): boolean {\n if (validFrom && timestamp < validFrom) return false;\n if (validUntil && timestamp > validUntil) return false;\n return true;\n}\n\nfunction durationScore(\n validFrom: Date | null | undefined,\n validUntil: Date | null | undefined,\n): number {\n if (validFrom && validUntil)\n return validUntil.getTime() - validFrom.getTime();\n if (validFrom || validUntil) return Number.MAX_SAFE_INTEGER - 1;\n return Number.MAX_SAFE_INTEGER;\n}\n\nfunction quantityRangeWidth(\n min: number | null | undefined,\n max: number | null | undefined,\n): number {\n if (min != null && max != null) return Math.max(0, max - min);\n if (min != null || max != null) return Number.MAX_SAFE_INTEGER - 1;\n return Number.MAX_SAFE_INTEGER;\n}\n\nfunction compareBasePriceSpecificity(\n a: Price,\n b: Price,\n context: PriceResolutionContext,\n): number {\n const aVariant =\n context.variantId !== undefined && a.variantId === context.variantId\n ? 1\n : 0;\n const bVariant =\n context.variantId !== undefined && b.variantId === context.variantId\n ? 1\n : 0;\n if (aVariant !== bVariant) return bVariant - aVariant;\n\n const hasGroupA = a.customerGroupId ? 1 : 0;\n const hasGroupB = b.customerGroupId ? 1 : 0;\n if (hasGroupA !== hasGroupB) return hasGroupB - hasGroupA;\n\n const aRange = quantityRangeWidth(a.minQuantity, a.maxQuantity);\n const bRange = quantityRangeWidth(b.minQuantity, b.maxQuantity);\n if (aRange !== bRange) return aRange - bRange;\n\n const aDuration = durationScore(a.validFrom, a.validUntil);\n const bDuration = durationScore(b.validFrom, b.validUntil);\n if (aDuration !== bDuration) return aDuration - bDuration;\n\n return b.createdAt.getTime() - a.createdAt.getTime();\n}\n\nfunction resolveModifierDelta(\n type: PriceModifierType,\n value: number,\n amountBefore: number,\n): number {\n switch (type) {\n case \"percentage_discount\":\n return -Math.round((amountBefore * value) / 100);\n case \"fixed_discount\":\n return -value;\n case \"markup\":\n return value;\n case \"override\":\n return value - amountBefore;\n default:\n return 0;\n }\n}\n\nfunction toGroupSet(context: PriceResolutionContext): Set<string> {\n return new Set(context.customerGroupIds ?? []);\n}\n\nfunction normalizeCurrency(currency: string): string {\n return currency.trim().toUpperCase();\n}\n\nexport class PricingService {\n private readonly repo: PricingRepository;\n private readonly catalogRepo: CatalogRepository;\n\n constructor(private deps: PricingServiceDeps) {\n this.repo = deps.repository;\n this.catalogRepo = deps.catalogRepository;\n }\n\n async setBasePrice(\n input: SetBasePriceInput,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Price>> {\n if (input.amount < 0) {\n return Err(\n new CommerceValidationError(\"Base price amount cannot be negative.\"),\n );\n }\n\n const entity = await this.catalogRepo.findEntityById(input.entityId, ctx);\n if (!entity) {\n return Err(\n new CommerceNotFoundError(\"Entity not found for price assignment.\"),\n );\n }\n\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n\n const priceData: PriceInsert = {\n organizationId: orgId,\n entityId: input.entityId,\n currency: normalizeCurrency(input.currency),\n amount: input.amount,\n metadata: input.metadata ?? {},\n variantId: input.variantId ?? null,\n customerGroupId: input.customerGroupId ?? null,\n minQuantity: input.minQuantity ?? null,\n maxQuantity: input.maxQuantity ?? null,\n validFrom: input.validFrom ?? null,\n validUntil: input.validUntil ?? null,\n };\n\n const record = await this.repo.createPrice(priceData, ctx);\n return Ok(record);\n }\n\n async createModifier(\n input: CreatePriceModifierInput,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<PriceModifier>> {\n if (!input.name) {\n return Err(new CommerceValidationError(\"Modifier name is required.\"));\n }\n\n // Validate modifier type\n const validTypes: PriceModifierType[] = [\n \"percentage_discount\",\n \"fixed_discount\",\n \"markup\",\n \"override\",\n ];\n if (!validTypes.includes(input.type)) {\n return Err(\n new CommerceValidationError(\n `Invalid modifier type \"${input.type}\". Must be one of: ${validTypes.join(\", \")}`,\n ),\n );\n }\n\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n\n const modifierData: PriceModifierInsert = {\n organizationId: orgId,\n name: input.name,\n type: input.type,\n value: input.value,\n priority: input.priority ?? 100,\n conditions: input.conditions ?? {},\n metadata: input.metadata ?? {},\n entityId: input.entityId ?? null,\n variantId: input.variantId ?? null,\n customerGroupId: input.customerGroupId ?? null,\n currency: input.currency ? normalizeCurrency(input.currency) : null,\n minQuantity: input.minQuantity ?? null,\n maxQuantity: input.maxQuantity ?? null,\n validFrom: input.validFrom ?? null,\n validUntil: input.validUntil ?? null,\n };\n\n const modifier = await this.repo.createModifier(modifierData, ctx);\n return Ok(modifier);\n }\n\n async listPrices(\n filter?: {\n entityId?: string;\n variantId?: string;\n currency?: string;\n customerGroupId?: string;\n },\n ctx?: TxContext,\n ): Promise<Result<{ prices: Price[]; modifiers: PriceModifier[] }>> {\n // Get all prices for the entity if specified, or filter after retrieval\n let prices: Price[] = [];\n if (filter?.entityId) {\n prices = await this.repo.findPricesByEntityId(filter.entityId, ctx);\n }\n // Note: For full list without entityId, we'd need a findAll method\n // For now, entityId is typically required for practical use\n\n // Apply additional filters\n if (filter?.variantId !== undefined) {\n prices = prices.filter((p) => p.variantId === filter.variantId);\n }\n if (filter?.currency !== undefined) {\n const normalizedCurrency = normalizeCurrency(filter.currency);\n prices = prices.filter((p) => p.currency === normalizedCurrency);\n }\n if (filter?.customerGroupId !== undefined) {\n prices = prices.filter(\n (p) => p.customerGroupId === filter.customerGroupId,\n );\n }\n\n // Get modifiers for the entity\n let modifiers: PriceModifier[] = [];\n if (filter?.entityId) {\n modifiers = await this.repo.findModifiersByEntityId(filter.entityId, ctx);\n }\n\n // Apply additional filters\n if (filter?.variantId !== undefined) {\n modifiers = modifiers.filter((m) => m.variantId === filter.variantId);\n }\n if (filter?.currency !== undefined) {\n const normalizedCurrency = normalizeCurrency(filter.currency);\n modifiers = modifiers.filter(\n (m) => m.currency === null || m.currency === normalizedCurrency,\n );\n }\n if (filter?.customerGroupId !== undefined) {\n modifiers = modifiers.filter(\n (m) =>\n m.customerGroupId === null ||\n m.customerGroupId === filter.customerGroupId,\n );\n }\n\n return Ok({ prices, modifiers });\n }\n\n async resolve(\n input: PriceResolutionContext,\n ctx?: TxContext,\n ): Promise<Result<ResolvedPrice>> {\n const entity = await this.catalogRepo.findEntityById(input.entityId, ctx);\n if (!entity) {\n return Err(\n new CommerceNotFoundError(`Entity ${input.entityId} not found.`),\n );\n }\n\n if (input.quantity <= 0) {\n return Err(\n new CommerceValidationError(\n \"Quantity must be greater than zero for price resolution.\",\n ),\n );\n }\n\n const timestamp = input.timestamp ?? new Date();\n const currency = normalizeCurrency(input.currency);\n const groupSet = toGroupSet(input);\n\n // Get matching prices from repository\n const allPrices = await this.repo.findPricesByEntityId(input.entityId, ctx);\n\n const matchingPrices = allPrices.filter((price) => {\n if (input.variantId !== undefined) {\n if (price.variantId !== null && price.variantId !== input.variantId)\n return false;\n } else if (price.variantId !== null) {\n return false;\n }\n if (price.currency !== currency) return false;\n if (\n !matchesQuantity(price.minQuantity, price.maxQuantity, input.quantity)\n )\n return false;\n if (!matchesWindow(price.validFrom, price.validUntil, timestamp))\n return false;\n if (\n price.customerGroupId !== null &&\n !groupSet.has(price.customerGroupId)\n )\n return false;\n return true;\n });\n\n if (matchingPrices.length === 0) {\n const metadataPrice =\n typeof entity.metadata?.basePrice === \"number\"\n ? Math.round(entity.metadata.basePrice)\n : undefined;\n if (metadataPrice === undefined) {\n return Err(\n new CommerceNotFoundError(\n `No base price configured for ${entity.slug} (${currency}).`,\n ),\n );\n }\n const fallback: ResolvedPrice = {\n baseAmount: metadataPrice,\n finalAmount: metadataPrice,\n currency,\n basePriceId: \"metadata:basePrice\",\n appliedModifiers: [],\n breakdown: [\n {\n label: \"Base price (entity metadata)\",\n amountBefore: metadataPrice,\n delta: 0,\n amountAfter: metadataPrice,\n },\n ],\n };\n return Ok(fallback);\n }\n\n const selectedBase = [...matchingPrices].sort((a, b) =>\n compareBasePriceSpecificity(a, b, input),\n )[0];\n if (!selectedBase) {\n return Err(\n new CommerceNotFoundError(\"No matching base price could be selected.\"),\n );\n }\n\n let runningAmount = selectedBase.amount;\n const breakdown: PriceBreakdownStep[] = [\n {\n label: \"Base price\",\n amountBefore: selectedBase.amount,\n delta: 0,\n amountAfter: selectedBase.amount,\n metadata: {\n priceId: selectedBase.id,\n customerGroupId: selectedBase.customerGroupId,\n minQuantity: selectedBase.minQuantity,\n maxQuantity: selectedBase.maxQuantity,\n },\n },\n ];\n\n const appliedModifiers: ResolvedPrice[\"appliedModifiers\"] = [];\n\n // Get matching modifiers (includes both entity-specific and global)\n const firstGroupId = groupSet.size > 0 ? [...groupSet][0] : undefined;\n const activeModifiers = await this.repo.findActiveModifiers(\n input.entityId,\n input.variantId,\n firstGroupId,\n currency,\n input.quantity,\n ctx,\n );\n\n // Additional filtering for multiple customer groups and conditions\n const modifiers = activeModifiers\n .filter((modifier) => {\n // Re-check customer group for multi-group support\n if (\n modifier.customerGroupId !== null &&\n !groupSet.has(modifier.customerGroupId)\n )\n return false;\n\n const conditions = modifier.conditions as Record<\n string,\n unknown\n > | null;\n const minSubtotal = conditions?.minSubtotal;\n if (typeof minSubtotal === \"number\" && runningAmount < minSubtotal)\n return false;\n\n return true;\n })\n .sort((a, b) => a.priority - b.priority);\n\n for (const modifier of modifiers) {\n const amountBefore = runningAmount;\n const rawDelta = resolveModifierDelta(\n modifier.type as PriceModifierType,\n modifier.value,\n amountBefore,\n );\n const delta = Math.max(-amountBefore, rawDelta);\n runningAmount = Math.max(0, amountBefore + delta);\n\n appliedModifiers.push({\n id: modifier.id,\n name: modifier.name,\n type: modifier.type as PriceModifierType,\n delta,\n value: modifier.value,\n priority: modifier.priority,\n });\n\n breakdown.push({\n label: `Modifier: ${modifier.name}`,\n amountBefore,\n delta,\n amountAfter: runningAmount,\n metadata: {\n type: modifier.type,\n priority: modifier.priority,\n },\n });\n }\n\n return Ok({\n baseAmount: selectedBase.amount,\n finalAmount: runningAmount,\n currency,\n basePriceId: selectedBase.id,\n appliedModifiers,\n breakdown,\n });\n }\n}\n",
|
|
114
|
+
"import {\n CommerceNotFoundError,\n CommerceValidationError,\n} from \"../../kernel/errors\";\nimport { Err, Ok, type Result } from \"../../kernel/result\";\nimport type { TxContext } from \"../../kernel/database/tx-context\";\nimport type {\n PromotionsRepository,\n Promotion,\n PromotionUsage,\n} from \"./repository\";\nimport type { CatalogRepository } from \"../catalog/repository\";\nimport type { OrdersRepository } from \"../orders/repository\";\nimport { DEFAULT_ORG_ID, resolveOrgId } from \"../../auth/org\";\nimport type { Actor } from \"../../auth/types\";\n\n// Re-export PromotionType for external use\nexport type PromotionType =\n | \"percentage_off_order\"\n | \"fixed_off_order\"\n | \"percentage_off_item\"\n | \"fixed_off_item\"\n | \"free_shipping\"\n | \"buy_x_get_y\";\n\ninterface PromotionServiceDeps {\n repository: PromotionsRepository;\n catalogRepository: CatalogRepository;\n ordersRepository: OrdersRepository;\n}\n\nexport interface PromotionLineItem {\n entityId: string;\n entityType: string;\n quantity: number;\n unitPrice: number;\n totalPrice: number;\n}\n\nexport interface PromotionEvaluationContext {\n orgId?: string;\n cartId?: string;\n customerId?: string;\n customerGroupIds?: string[];\n currency: string;\n subtotal: number;\n lineItems: PromotionLineItem[];\n promotionCodes?: string[];\n timestamp?: Date;\n}\n\nexport interface PromotionConditions {\n minimumOrderValue?: number;\n minimumQuantity?: number;\n entityTypes?: string[];\n categories?: string[];\n customerGroups?: string[];\n firstOrderOnly?: boolean;\n}\n\nexport type { CreatePromotionInput } from \"./schemas\";\nimport type { CreatePromotionInput } from \"./schemas\";\n\nexport interface AppliedPromotion {\n promotionId: string;\n code?: string;\n type: PromotionType;\n discountAmount: number;\n freeShipping: boolean;\n description: string;\n}\n\nexport interface PromotionApplicationResult {\n totalDiscount: number;\n freeShipping: boolean;\n applied: AppliedPromotion[];\n rejectedCodes: Array<{ code: string; reason: string }>;\n}\n\nfunction matchesWindow(promotion: Promotion, timestamp: Date): boolean {\n if (!promotion.isActive) return false;\n if (promotion.validFrom && timestamp < promotion.validFrom) return false;\n if (promotion.validUntil && timestamp > promotion.validUntil) return false;\n return true;\n}\n\nfunction toConditions(\n raw: Record<string, unknown> | null | undefined,\n): PromotionConditions {\n if (!raw) return {};\n const conditions: PromotionConditions = {};\n if (typeof raw.minimumOrderValue === \"number\") {\n conditions.minimumOrderValue = raw.minimumOrderValue;\n }\n if (typeof raw.minimumQuantity === \"number\") {\n conditions.minimumQuantity = raw.minimumQuantity;\n }\n if (Array.isArray(raw.entityTypes)) {\n conditions.entityTypes = raw.entityTypes.filter(\n (item): item is string => typeof item === \"string\",\n );\n }\n if (Array.isArray(raw.categories)) {\n conditions.categories = raw.categories.filter(\n (item): item is string => typeof item === \"string\",\n );\n }\n if (Array.isArray(raw.customerGroups)) {\n conditions.customerGroups = raw.customerGroups.filter(\n (item): item is string => typeof item === \"string\",\n );\n }\n if (typeof raw.firstOrderOnly === \"boolean\") {\n conditions.firstOrderOnly = raw.firstOrderOnly;\n }\n return conditions;\n}\n\nfunction roundMoney(amount: number): number {\n return Math.max(0, Math.round(amount));\n}\n\nfunction totalQuantity(items: PromotionLineItem[]): number {\n return items.reduce((sum, item) => sum + item.quantity, 0);\n}\n\nfunction sortByPriority(promotions: Promotion[]): Promotion[] {\n return [...promotions].sort((a, b) => a.priority - b.priority);\n}\n\nexport class PromotionService {\n private readonly repo: PromotionsRepository;\n private readonly catalogRepo: CatalogRepository;\n private readonly ordersRepo: OrdersRepository;\n\n constructor(private deps: PromotionServiceDeps) {\n this.repo = deps.repository;\n this.catalogRepo = deps.catalogRepository;\n this.ordersRepo = deps.ordersRepository;\n }\n\n async create(\n input: CreatePromotionInput,\n actor?: Actor | null,\n ctx?: TxContext,\n ): Promise<Result<Promotion>> {\n if (!input.name) {\n return Err(new CommerceValidationError(\"Promotion name is required.\"));\n }\n if (input.value < 0) {\n return Err(\n new CommerceValidationError(\"Promotion value cannot be negative.\"),\n );\n }\n\n // Validate promotion type\n const validTypes: PromotionType[] = [\n \"percentage_off_order\",\n \"fixed_off_order\",\n \"percentage_off_item\",\n \"fixed_off_item\",\n \"free_shipping\",\n \"buy_x_get_y\",\n ];\n if (!validTypes.includes(input.type)) {\n return Err(\n new CommerceValidationError(\n `Invalid promotion type \"${input.type}\". Must be one of: ${validTypes.join(\", \")}`,\n ),\n );\n }\n\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n\n if (input.code) {\n const normalized = input.code.trim().toUpperCase();\n const existing = await this.repo.findByCode(orgId, normalized, ctx);\n if (existing) {\n return Err(\n new CommerceValidationError(\n `Promotion code ${normalized} already exists.`,\n ),\n );\n }\n }\n\n const promotion = await this.repo.create(\n {\n organizationId: orgId,\n name: input.name,\n type: input.type,\n value: roundMoney(input.value),\n isAutomatic: input.isAutomatic ?? false,\n isActive: input.isActive ?? true,\n priority: input.priority ?? 100,\n conditions: (input.conditions ?? {}) as Record<string, unknown>,\n metadata: input.metadata ?? {},\n code: input.code ? input.code.trim().toUpperCase() : null,\n buyQuantity: input.buyQuantity ?? null,\n getQuantity: input.getQuantity ?? null,\n usageLimitTotal: input.usageLimitTotal ?? null,\n usageLimitPerCustomer: input.usageLimitPerCustomer ?? null,\n validFrom: input.validFrom ?? null,\n validUntil: input.validUntil ?? null,\n },\n ctx,\n );\n\n return Ok(promotion);\n }\n\n async deactivate(orgId: string, id: string, ctx?: TxContext): Promise<Result<Promotion>> {\n const promotion = await this.repo.findById(orgId, id, ctx);\n if (!promotion) {\n return Err(new CommerceNotFoundError(\"Promotion not found.\"));\n }\n\n const updated = await this.repo.update(id, { isActive: false }, ctx);\n if (!updated) {\n return Err(new CommerceNotFoundError(\"Promotion not found.\"));\n }\n return Ok(updated);\n }\n\n async listActive(\n actor?: Actor | null,\n timestamp = new Date(),\n ctx?: TxContext,\n ): Promise<Result<Promotion[]>> {\n const orgId = resolveOrgId(actor ?? ctx?.actor ?? null);\n const active = await this.repo.findActive(orgId, ctx);\n // Further filter by timestamp in case repo returns slightly stale results\n const filtered = active.filter((p) => matchesWindow(p, timestamp));\n return Ok(sortByPriority(filtered));\n }\n\n async validate(\n code: string,\n context: PromotionEvaluationContext,\n ctx?: TxContext,\n ): Promise<Result<Promotion>> {\n const normalized = code.trim().toUpperCase();\n const evalOrgId = context.orgId ?? DEFAULT_ORG_ID;\n const promotion = await this.repo.findByCode(evalOrgId, normalized, ctx);\n if (!promotion) {\n return Err(\n new CommerceNotFoundError(`Promotion code ${normalized} not found.`),\n );\n }\n\n const validation = await this.validatePromotionForContext(\n promotion,\n context,\n context.timestamp ?? new Date(),\n ctx,\n );\n if (validation !== undefined) {\n return Err(new CommerceValidationError(validation));\n }\n return Ok(promotion);\n }\n\n async apply(\n code: string,\n context: PromotionEvaluationContext,\n ctx?: TxContext,\n ): Promise<Result<PromotionApplicationResult>> {\n const validation = await this.validate(code, context, ctx);\n if (!validation.ok) return validation;\n\n const evaluated = await this.evaluatePromotion(\n validation.value,\n context,\n ctx,\n );\n return Ok({\n totalDiscount: evaluated.discountAmount,\n freeShipping: evaluated.freeShipping,\n applied: [evaluated],\n rejectedCodes: [],\n });\n }\n\n async applyPromotions(\n context: PromotionEvaluationContext,\n ctx?: TxContext,\n ): Promise<Result<PromotionApplicationResult>> {\n const timestamp = context.timestamp ?? new Date();\n const applyOrgId = context.orgId ?? DEFAULT_ORG_ID;\n const result: PromotionApplicationResult = {\n totalDiscount: 0,\n freeShipping: false,\n applied: [],\n rejectedCodes: [],\n };\n\n const selectedPromotions: Promotion[] = [];\n\n // Process explicit promotion codes\n const codeSet = new Set(\n (context.promotionCodes ?? []).map((code) => code.trim().toUpperCase()),\n );\n if (codeSet.size > 0) {\n for (const code of codeSet) {\n const promotion = await this.repo.findByCode(applyOrgId, code, ctx);\n if (!promotion) {\n result.rejectedCodes.push({ code, reason: \"Code not found.\" });\n continue;\n }\n const reason = await this.validatePromotionForContext(\n promotion,\n context,\n timestamp,\n ctx,\n );\n if (reason !== undefined) {\n result.rejectedCodes.push({ code, reason });\n continue;\n }\n selectedPromotions.push(promotion);\n }\n }\n\n // Process automatic promotions\n const automaticPromotions = await this.repo.findAutomatic(applyOrgId, ctx);\n for (const promotion of automaticPromotions) {\n const reason = await this.validatePromotionForContext(\n promotion,\n context,\n timestamp,\n ctx,\n );\n if (reason !== undefined) continue;\n selectedPromotions.push(promotion);\n }\n\n for (const promotion of sortByPriority(selectedPromotions)) {\n const evaluated = await this.evaluatePromotion(promotion, context, ctx);\n if (evaluated.discountAmount <= 0 && !evaluated.freeShipping) continue;\n result.totalDiscount += evaluated.discountAmount;\n result.freeShipping = result.freeShipping || evaluated.freeShipping;\n result.applied.push(evaluated);\n }\n\n result.totalDiscount = Math.min(\n roundMoney(result.totalDiscount),\n roundMoney(context.subtotal),\n );\n return Ok(result);\n }\n\n async recordUsage(\n input: {\n promotions: AppliedPromotion[];\n customerId?: string;\n orderId?: string;\n },\n ctx?: TxContext,\n ): Promise<Result<PromotionUsage[]>> {\n const usages: PromotionUsage[] = [];\n for (const applied of input.promotions) {\n const usage = await this.repo.createUsage(\n {\n promotionId: applied.promotionId,\n customerId: input.customerId ?? null,\n orderId: input.orderId ?? null,\n },\n ctx,\n );\n usages.push(usage);\n }\n return Ok(usages);\n }\n\n private async validatePromotionForContext(\n promotion: Promotion,\n context: PromotionEvaluationContext,\n timestamp: Date,\n ctx?: TxContext,\n ): Promise<string | undefined> {\n if (!matchesWindow(promotion, timestamp)) {\n return \"Promotion is inactive or outside validity window.\";\n }\n\n const conditions = toConditions(\n promotion.conditions as Record<string, unknown> | null,\n );\n if (\n conditions.minimumOrderValue !== undefined &&\n roundMoney(context.subtotal) < roundMoney(conditions.minimumOrderValue)\n ) {\n return `Requires minimum order value of ${conditions.minimumOrderValue}.`;\n }\n\n if (\n conditions.minimumQuantity !== undefined &&\n totalQuantity(context.lineItems) < conditions.minimumQuantity\n ) {\n return `Requires minimum quantity of ${conditions.minimumQuantity}.`;\n }\n\n if (conditions.customerGroups && conditions.customerGroups.length > 0) {\n const set = new Set(context.customerGroupIds ?? []);\n const matchesGroup = conditions.customerGroups.some((group) =>\n set.has(group),\n );\n if (!matchesGroup) {\n return \"Customer group not eligible for this promotion.\";\n }\n }\n\n if (conditions.entityTypes && conditions.entityTypes.length > 0) {\n const hasType = context.lineItems.some((lineItem) =>\n conditions.entityTypes!.includes(lineItem.entityType),\n );\n if (!hasType) return \"Cart does not include required entity type.\";\n }\n\n if (conditions.categories && conditions.categories.length > 0) {\n const categoryMatches = await this.checkCategoryMatch(\n context.lineItems,\n conditions.categories,\n ctx,\n );\n if (!categoryMatches) return \"Cart does not include required category.\";\n }\n\n if (conditions.firstOrderOnly) {\n if (!context.customerId) {\n return \"First-order promotion requires authenticated customer.\";\n }\n const orders = await this.ordersRepo.findByCustomerId(\n context.orgId ?? DEFAULT_ORG_ID,\n context.customerId,\n ctx,\n );\n if (orders.length > 0) {\n return \"Promotion is valid for first order only.\";\n }\n }\n\n // Check usage limits\n const usageCount = await this.repo.countUsages(promotion.id, ctx);\n if (\n promotion.usageLimitTotal !== null &&\n usageCount >= promotion.usageLimitTotal\n ) {\n return \"Promotion usage limit reached.\";\n }\n\n if (promotion.usageLimitPerCustomer !== null && context.customerId) {\n const customerUses = await this.repo.countUsagesByCustomer(\n promotion.id,\n context.customerId,\n ctx,\n );\n if (customerUses >= promotion.usageLimitPerCustomer) {\n return \"Promotion per-customer usage limit reached.\";\n }\n }\n\n return undefined;\n }\n\n private async checkCategoryMatch(\n lineItems: PromotionLineItem[],\n categorySlugs: string[],\n ctx?: TxContext,\n ): Promise<boolean> {\n for (const lineItem of lineItems) {\n const entityCategories = await this.catalogRepo.findEntityCategories(\n lineItem.entityId,\n ctx,\n );\n for (const link of entityCategories) {\n const category = await this.catalogRepo.findCategoryById(\n link.categoryId,\n ctx,\n );\n if (category && categorySlugs.includes(category.slug)) {\n return true;\n }\n }\n }\n return false;\n }\n\n private async evaluatePromotion(\n promotion: Promotion,\n context: PromotionEvaluationContext,\n ctx?: TxContext,\n ): Promise<AppliedPromotion> {\n const conditions = toConditions(\n promotion.conditions as Record<string, unknown> | null,\n );\n const eligibleItems = await this.filterEligibleLineItems(\n context.lineItems,\n conditions,\n ctx,\n );\n const eligibleSubtotal = eligibleItems.reduce(\n (sum, item) => sum + item.totalPrice,\n 0,\n );\n\n let discountAmount = 0;\n let freeShipping = false;\n\n switch (promotion.type) {\n case \"percentage_off_order\":\n discountAmount = Math.round((context.subtotal * promotion.value) / 100);\n break;\n case \"fixed_off_order\":\n discountAmount = promotion.value;\n break;\n case \"percentage_off_item\":\n discountAmount = Math.round((eligibleSubtotal * promotion.value) / 100);\n break;\n case \"fixed_off_item\": {\n const totalUnits = eligibleItems.reduce(\n (sum, item) => sum + item.quantity,\n 0,\n );\n discountAmount = totalUnits * promotion.value;\n break;\n }\n case \"free_shipping\":\n freeShipping = true;\n break;\n case \"buy_x_get_y\": {\n const buy = promotion.buyQuantity ?? 0;\n const get = promotion.getQuantity ?? 0;\n const totalUnits = eligibleItems.reduce(\n (sum, item) => sum + item.quantity,\n 0,\n );\n if (buy > 0 && get > 0 && totalUnits > 0) {\n const groups = Math.floor(totalUnits / (buy + get));\n const freeUnits = groups * get;\n const minUnitPrice = eligibleItems.length\n ? Math.min(...eligibleItems.map((item) => item.unitPrice))\n : 0;\n discountAmount = freeUnits * minUnitPrice;\n }\n break;\n }\n default:\n discountAmount = 0;\n }\n\n return {\n promotionId: promotion.id,\n type: promotion.type as PromotionType,\n discountAmount: roundMoney(discountAmount),\n freeShipping,\n description: promotion.code\n ? `Promotion ${promotion.code}`\n : `Promotion ${promotion.name}`,\n ...(promotion.code !== null ? { code: promotion.code } : {}),\n };\n }\n\n private async filterEligibleLineItems(\n lineItems: PromotionLineItem[],\n conditions: PromotionConditions,\n ctx?: TxContext,\n ): Promise<PromotionLineItem[]> {\n const eligible: PromotionLineItem[] = [];\n\n for (const lineItem of lineItems) {\n if (conditions.entityTypes && conditions.entityTypes.length > 0) {\n if (!conditions.entityTypes.includes(lineItem.entityType)) continue;\n }\n if (conditions.categories && conditions.categories.length > 0) {\n const entityCats = await this.catalogRepo.findEntityCategories(\n lineItem.entityId,\n ctx,\n );\n const hasCategory = await (async () => {\n for (const link of entityCats) {\n const category = await this.catalogRepo.findCategoryById(\n link.categoryId,\n ctx,\n );\n if (category && conditions.categories!.includes(category.slug)) {\n return true;\n }\n }\n return false;\n })();\n if (!hasCategory) continue;\n }\n eligible.push(lineItem);\n }\n\n return eligible;\n }\n}\n",
|
|
115
|
+
"import { CommerceValidationError } from \"../../kernel/errors\";\nimport { Err, Ok, type Result } from \"../../kernel/result\";\nimport type {\n TaxAdapter,\n TaxCalculationParams,\n TaxCalculationResult,\n TaxReportParams,\n TaxVoidParams,\n} from \"./adapter\";\n\ninterface TaxServiceDeps {\n adapter: TaxAdapter | undefined;\n}\n\nexport class TaxService {\n private adapter: TaxAdapter | undefined;\n\n constructor(deps: TaxServiceDeps) {\n this.adapter = deps.adapter;\n }\n\n async calculate(params: TaxCalculationParams): Promise<Result<TaxCalculationResult>> {\n if (!this.adapter) {\n return Ok({\n amountToCollect: 0,\n taxableAmount:\n params.lineItems.reduce(\n (sum, lineItem) => sum + lineItem.unitPrice * lineItem.quantity - (lineItem.discount ?? 0),\n 0,\n ) + params.shippingAmount,\n rate: 0,\n });\n }\n return this.adapter.calculateTax(params);\n }\n\n async reportTransaction(params: TaxReportParams): Promise<Result<{ transactionId: string }>> {\n if (!this.adapter) return Ok({ transactionId: params.transactionId });\n return this.adapter.reportTransaction(params);\n }\n\n async voidTransaction(params: TaxVoidParams): Promise<Result<{ transactionId: string }>> {\n if (!this.adapter) return Ok({ transactionId: params.transactionId });\n return this.adapter.voidTransaction(params);\n }\n\n requireConfigured(): Result<TaxAdapter> {\n if (!this.adapter) {\n return Err(new CommerceValidationError(\"Tax adapter is not configured.\"));\n }\n return Ok(this.adapter);\n }\n}\n",
|
|
116
|
+
"import type { CommerceConfig } from \"../../config/types\";\nimport type { TxContext } from \"../../kernel/database/tx-context\";\nimport type { CatalogRepository } from \"../catalog/repository\";\n\nexport interface ShippingAddress {\n country: string;\n postalCode: string;\n state?: string;\n city?: string;\n line1?: string;\n}\n\nexport interface ShippingLineItem {\n entityId: string;\n variantId?: string;\n quantity: number;\n resolvedTotal: number;\n}\n\nexport type ShippingStrategy =\n | {\n type: \"flat\";\n flatRate: number;\n freeShippingThreshold?: number;\n }\n | {\n type: \"weight_based\";\n brackets: Array<{ upToGrams: number; cost: number }>;\n fallbackCost: number;\n freeShippingThreshold?: number;\n };\n\nexport interface ShippingCalculationInput {\n lineItems: ShippingLineItem[];\n subtotalAfterDiscount: number;\n currency: string;\n address?: ShippingAddress;\n isFreeShipping: boolean;\n}\n\nasync function resolveWeightGrams(\n catalogRepo: CatalogRepository,\n entityId: string,\n variantId: string | undefined,\n ctx?: TxContext,\n): Promise<number> {\n if (variantId !== undefined) {\n const variant = await catalogRepo.findVariantById(variantId, ctx);\n const weightFromVariant = (\n variant?.metadata as Record<string, unknown> | null\n )?.weightGrams;\n if (\n typeof weightFromVariant === \"number\" &&\n Number.isFinite(weightFromVariant)\n ) {\n return Math.max(0, Math.round(weightFromVariant));\n }\n }\n\n const entity = await catalogRepo.findEntityById(entityId, ctx);\n const weightFromEntity = (entity?.metadata as Record<string, unknown> | null)\n ?.weightGrams;\n if (\n typeof weightFromEntity === \"number\" &&\n Number.isFinite(weightFromEntity)\n ) {\n return Math.max(0, Math.round(weightFromEntity));\n }\n\n return 0;\n}\n\nasync function isShippableEntity(\n config: CommerceConfig,\n catalogRepo: CatalogRepository,\n entityId: string,\n ctx?: TxContext,\n): Promise<boolean> {\n const entity = await catalogRepo.findEntityById(entityId, ctx);\n if (!entity) return false;\n const fulfillment = config.entities?.[entity.type]?.fulfillment;\n return (\n fulfillment === \"physical\" ||\n fulfillment === \"internal-transfer\" ||\n fulfillment === undefined\n );\n}\n\nfunction resolveStrategy(config: CommerceConfig): ShippingStrategy {\n const shipping = config.shipping;\n if (!shipping) {\n return {\n type: \"flat\",\n flatRate: 0,\n };\n }\n\n if (shipping.type === \"weight_based\") {\n return {\n type: \"weight_based\",\n brackets: [...shipping.brackets].sort(\n (a, b) => a.upToGrams - b.upToGrams,\n ),\n fallbackCost: shipping.fallbackCost,\n ...(shipping.freeShippingThreshold !== undefined\n ? { freeShippingThreshold: shipping.freeShippingThreshold }\n : {}),\n };\n }\n\n return {\n type: \"flat\",\n flatRate: shipping.flatRate,\n ...(shipping.freeShippingThreshold !== undefined\n ? { freeShippingThreshold: shipping.freeShippingThreshold }\n : {}),\n };\n}\n\nexport async function calculateShippingCost(\n config: CommerceConfig,\n catalogRepo: CatalogRepository,\n input: ShippingCalculationInput,\n ctx?: TxContext,\n): Promise<{ amount: number; strategy: string; weightGrams: number }> {\n if (input.isFreeShipping) {\n return { amount: 0, strategy: \"promotion:free_shipping\", weightGrams: 0 };\n }\n\n const strategy = resolveStrategy(config);\n if (\n strategy.freeShippingThreshold !== undefined &&\n input.subtotalAfterDiscount >= strategy.freeShippingThreshold\n ) {\n return { amount: 0, strategy: \"threshold:free_shipping\", weightGrams: 0 };\n }\n\n // Filter to shippable items\n const shippableFlags = await Promise.all(\n input.lineItems.map((lineItem) =>\n isShippableEntity(config, catalogRepo, lineItem.entityId, ctx),\n ),\n );\n const shippableItems = input.lineItems.filter((_, i) => shippableFlags[i]);\n\n if (shippableItems.length === 0) {\n return {\n amount: 0,\n strategy: `${strategy.type}:digital_only`,\n weightGrams: 0,\n };\n }\n\n // Calculate total weight\n const weights = await Promise.all(\n shippableItems.map((lineItem) =>\n resolveWeightGrams(\n catalogRepo,\n lineItem.entityId,\n lineItem.variantId,\n ctx,\n ),\n ),\n );\n const weightGrams = shippableItems.reduce(\n (sum, lineItem, i) => sum + (weights[i] ?? 0) * lineItem.quantity,\n 0,\n );\n\n if (strategy.type === \"flat\") {\n return {\n amount: Math.max(0, Math.round(strategy.flatRate)),\n strategy: \"flat\",\n weightGrams,\n };\n }\n\n const matchedBracket = strategy.brackets.find(\n (bracket) => weightGrams <= bracket.upToGrams,\n );\n return {\n amount: matchedBracket\n ? Math.max(0, Math.round(matchedBracket.cost))\n : Math.max(0, Math.round(strategy.fallbackCost)),\n strategy: \"weight_based\",\n weightGrams,\n };\n}\n",
|
|
117
|
+
"import type { CommerceConfig } from \"../../config/types\";\nimport { Ok, type Result } from \"../../kernel/result\";\nimport type { TxContext } from \"../../kernel/database/tx-context\";\nimport type { CatalogRepository } from \"../catalog/repository\";\nimport {\n calculateShippingCost,\n type ShippingAddress,\n type ShippingLineItem,\n} from \"./calculator\";\n\ninterface ShippingServiceDeps {\n config: CommerceConfig;\n catalogRepository: CatalogRepository;\n}\n\nexport interface CalculateShippingInput {\n lineItems: ShippingLineItem[];\n subtotalAfterDiscount: number;\n currency: string;\n address?: ShippingAddress;\n isFreeShipping?: boolean;\n}\n\nexport class ShippingService {\n private readonly catalogRepo: CatalogRepository;\n\n constructor(private deps: ShippingServiceDeps) {\n this.catalogRepo = deps.catalogRepository;\n }\n\n async calculate(\n input: CalculateShippingInput,\n ctx?: TxContext,\n ): Promise<\n Result<{ amount: number; strategy: string; weightGrams: number }>\n > {\n const result = await calculateShippingCost(\n this.deps.config,\n this.catalogRepo,\n {\n lineItems: input.lineItems,\n subtotalAfterDiscount: input.subtotalAfterDiscount,\n currency: input.currency,\n isFreeShipping: input.isFreeShipping ?? false,\n ...(input.address !== undefined ? { address: input.address } : {}),\n },\n ctx,\n );\n return Ok(result);\n }\n}\n",
|
|
118
|
+
"import { Ok, type Result } from \"../../kernel/result\";\nimport { resolveOrgId } from \"../../auth/org\";\nimport type { TxContext } from \"../../kernel/database/tx-context\";\nimport type { CatalogRepository, SellableEntity } from \"../catalog/repository\";\nimport type {\n SearchAdapter,\n SearchDocument,\n SearchFilters,\n SearchQueryParams,\n SearchQueryResult,\n SearchSuggestParams,\n} from \"./adapter\";\n\ninterface SearchServiceDeps {\n catalogRepository: CatalogRepository;\n adapter?: SearchAdapter;\n defaultFacets?: string[];\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values)];\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction tokenize(query: string): string[] {\n return query\n .toLowerCase()\n .split(/\\s+/)\n .map((part) => part.trim())\n .filter(Boolean);\n}\n\nfunction includesAllTokens(haystack: string, tokens: string[]): boolean {\n if (tokens.length === 0) return true;\n const lower = haystack.toLowerCase();\n return tokens.every((token) => lower.includes(token));\n}\n\nfunction scoreText(document: SearchDocument, tokens: string[]): number {\n if (tokens.length === 0) return 1;\n\n const title = document.title.toLowerCase();\n const text = document.text.toLowerCase();\n\n let score = 0;\n for (const token of tokens) {\n if (title.includes(token)) score += 2;\n if (text.includes(token)) score += 1;\n }\n\n return score;\n}\n\nexport class SearchService {\n constructor(private deps: SearchServiceDeps) {}\n\n private async entityCategories(\n entityId: string,\n ctx?: TxContext,\n ): Promise<string[]> {\n const entries = await this.deps.catalogRepository.findEntityCategories(\n entityId,\n ctx,\n );\n\n const slugs = (\n await Promise.all(\n entries.map(async (entry) => {\n const category = await this.deps.catalogRepository.findCategoryById(\n entry.categoryId,\n ctx,\n );\n return category?.slug;\n }),\n )\n ).filter((slug): slug is string => typeof slug === \"string\");\n\n return unique(slugs);\n }\n\n private async entityBrands(\n entityId: string,\n ctx?: TxContext,\n ): Promise<string[]> {\n const entries = await this.deps.catalogRepository.findEntityBrands(\n entityId,\n ctx,\n );\n\n const slugs = (\n await Promise.all(\n entries.map(async (entry) => {\n const brand = await this.deps.catalogRepository.findBrandById(\n entry.brandId,\n ctx,\n );\n return brand?.slug;\n }),\n )\n ).filter((slug): slug is string => typeof slug === \"string\");\n\n return unique(slugs);\n }\n\n private async buildDocument(\n entity: SellableEntity,\n ctx?: TxContext,\n ): Promise<SearchDocument> {\n const attributes =\n await this.deps.catalogRepository.findAttributesByEntityId(\n entity.id,\n ctx,\n );\n const primary = attributes[0];\n const title = primary?.title ?? entity.slug;\n const description = primary?.description;\n const categories = await this.entityCategories(entity.id, ctx);\n const brands = await this.entityBrands(entity.id, ctx);\n\n const textParts: string[] = [\n entity.slug,\n title,\n description ?? \"\",\n ...categories,\n ...brands,\n ...attributes.map((attr) => attr.title),\n ...attributes.map((attr) => attr.description ?? \"\"),\n ];\n\n return {\n id: entity.id,\n type: entity.type,\n slug: entity.slug,\n title,\n ...(description ? { description } : {}),\n status: entity.status,\n categories,\n brands,\n text: textParts.join(\" \").trim(),\n payload: {\n metadata: entity.metadata ?? undefined,\n },\n };\n }\n\n private async allDocuments(ctx?: TxContext): Promise<SearchDocument[]> {\n const orgId = resolveOrgId(ctx?.actor ?? null);\n const entities = await this.deps.catalogRepository.findEntities(\n orgId,\n undefined,\n ctx,\n );\n return Promise.all(\n entities.map((entity) => this.buildDocument(entity, ctx)),\n );\n }\n\n private matchesFilters(\n document: SearchDocument,\n filters: SearchFilters | undefined,\n ): boolean {\n if (!filters) return true;\n if (filters.type && document.type !== filters.type) return false;\n if (filters.status && document.status !== filters.status) return false;\n if (filters.category && !document.categories.includes(filters.category))\n return false;\n if (filters.brand && !document.brands.includes(filters.brand)) return false;\n return true;\n }\n\n private computeFacets(\n documents: SearchDocument[],\n requested?: string[],\n ): Record<string, Record<string, number>> {\n const facets =\n requested && requested.length > 0\n ? requested\n : (this.deps.defaultFacets ?? [\"type\", \"category\", \"brand\", \"status\"]);\n const output: Record<string, Record<string, number>> = {};\n\n for (const facet of facets) {\n if (facet === \"type\") {\n output.type = {};\n for (const document of documents) {\n output.type[document.type] = (output.type[document.type] ?? 0) + 1;\n }\n }\n\n if (facet === \"status\") {\n output.status = {};\n for (const document of documents) {\n const status = document.status ?? \"unknown\";\n output.status[status] = (output.status[status] ?? 0) + 1;\n }\n }\n\n if (facet === \"category\" || facet === \"categories\") {\n output.category = {};\n for (const document of documents) {\n for (const category of document.categories) {\n output.category[category] = (output.category[category] ?? 0) + 1;\n }\n }\n }\n\n if (facet === \"brand\" || facet === \"brands\") {\n output.brand = {};\n for (const document of documents) {\n for (const brand of document.brands) {\n output.brand[brand] = (output.brand[brand] ?? 0) + 1;\n }\n }\n }\n }\n\n return output;\n }\n\n async syncEntity(entityId: string, ctx?: TxContext): Promise<Result<void>> {\n if (!this.deps.adapter) return Ok(undefined);\n\n const entity = await this.deps.catalogRepository.findEntityById(\n entityId,\n ctx,\n );\n if (!entity) {\n return this.deps.adapter.remove([entityId]);\n }\n\n return this.deps.adapter.index([await this.buildDocument(entity, ctx)]);\n }\n\n async query(\n params: SearchQueryParams,\n ctx?: TxContext,\n ): Promise<Result<SearchQueryResult>> {\n const page = clamp(params.page ?? 1, 1, 100000);\n const limit = clamp(params.limit ?? 20, 1, 100);\n\n if (this.deps.adapter) {\n return this.deps.adapter.search({\n ...params,\n page,\n limit,\n });\n }\n\n const tokens = tokenize(params.query);\n const allDocs = await this.allDocuments(ctx);\n const filtered = allDocs.filter((document) => {\n if (!this.matchesFilters(document, params.filters)) return false;\n if (tokens.length === 0) return true;\n return includesAllTokens(document.text, tokens);\n });\n\n const scored = filtered\n .map((document) => ({\n document,\n score: scoreText(document, tokens),\n }))\n .sort((first, second) => {\n if (second.score !== first.score) return second.score - first.score;\n return first.document.title.localeCompare(second.document.title);\n });\n\n const offset = (page - 1) * limit;\n const hits = scored.slice(offset, offset + limit).map((row) => ({\n id: row.document.id,\n score: row.score,\n document: row.document,\n }));\n\n return Ok({\n hits,\n total: scored.length,\n page,\n limit,\n facets: this.computeFacets(filtered, params.facets),\n });\n }\n\n async suggest(\n params: SearchSuggestParams,\n ctx?: TxContext,\n ): Promise<Result<string[]>> {\n const limit = clamp(params.limit ?? 10, 1, 25);\n const prefix = params.prefix.trim().toLowerCase();\n\n if (prefix.length === 0) return Ok([]);\n\n if (this.deps.adapter) {\n return this.deps.adapter.suggest({\n ...params,\n prefix,\n limit,\n });\n }\n\n const allDocs = await this.allDocuments(ctx);\n const titles = allDocs\n .filter(\n (document) =>\n (!params.type || document.type === params.type) &&\n document.title.toLowerCase().startsWith(prefix),\n )\n .map((document) => document.title)\n .filter((title, index, list) => list.indexOf(title) === index)\n .slice(0, limit);\n\n return Ok(titles);\n }\n}\n",
|
|
119
|
+
"import { createHmac } from \"node:crypto\";\n\nexport function signWebhookPayload(secret: string, payload: unknown): string {\n const body = typeof payload === \"string\" ? payload : JSON.stringify(payload);\n return createHmac(\"sha256\", secret).update(body).digest(\"hex\");\n}\n",
|
|
120
|
+
"import { signWebhookPayload } from \"./signing\";\nimport { isPrivateIp } from \"./ssrf-guard\";\nimport type { WebhooksRepository } from \"./repository\";\n\n/**\n * SSRF prevention: reject webhook URLs targeting private/internal hosts.\n * Blocks RFC 1918, loopback, link-local, and common internal domains.\n */\nconst PRIVATE_HOST_PATTERNS = [\n /^127\\./, // loopback\n /^10\\./, // RFC 1918 class A\n /^172\\.(1[6-9]|2[0-9]|3[01])\\./, // RFC 1918 class B\n /^192\\.168\\./, // RFC 1918 class C\n /^169\\.254\\./, // link-local / AWS IMDS\n /^0\\.0\\.0\\.0/, // unspecified\n /^localhost$/i,\n /\\.local$/i,\n /\\.internal$/i,\n];\n\nfunction validateWebhookUrl(url: string): void {\n const parsed = new URL(url);\n\n if (process.env.NODE_ENV === \"production\" && parsed.protocol !== \"https:\") {\n throw new Error(\"Webhook URLs must use HTTPS in production.\");\n }\n\n const hostname = parsed.hostname;\n for (const pattern of PRIVATE_HOST_PATTERNS) {\n if (pattern.test(hostname)) {\n throw new Error(`Webhook URLs cannot target private hosts: ${hostname}`);\n }\n }\n}\n\n/**\n * Resolve the webhook URL hostname via DNS and verify the resolved IP is not\n * private. This closes the DNS rebinding gap where a hostname initially\n * resolves to a public IP but later rebinds to an internal address.\n */\nasync function validateResolvedIp(url: string): Promise<void> {\n const { lookup } = await import(\"node:dns/promises\");\n const parsed = new URL(url);\n const hostname = parsed.hostname.replace(/^\\[|\\]$/g, \"\");\n\n // Skip DNS resolution for raw IP addresses — they are already checked\n // by validateWebhookUrl via PRIVATE_HOST_PATTERNS.\n const isIpLiteral = /^[\\d.]+$/.test(hostname) || hostname.includes(\":\");\n if (isIpLiteral) return;\n\n try {\n const { address } = await lookup(hostname);\n if (isPrivateIp(address)) {\n throw new Error(\n `Webhook URL hostname \"${hostname}\" resolved to private IP ${address}`,\n );\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes(\"resolved to private\")) {\n throw err;\n }\n throw new Error(`Failed to resolve webhook URL hostname \"${hostname}\": ${err}`);\n }\n}\n\ninterface WorkerDeps {\n repository: WebhooksRepository;\n fetchImpl?: typeof fetch;\n}\n\nexport class WebhookDeliveryWorker {\n private fetchImpl: typeof fetch;\n\n constructor(private deps: WorkerDeps) {\n this.fetchImpl = deps.fetchImpl ?? fetch;\n }\n\n async deliver(args: {\n endpoint: { id: string; url: string; secret: string };\n eventName: string;\n payload: unknown;\n }): Promise<void> {\n // SSRF prevention: validate URL string patterns + resolved DNS IP\n validateWebhookUrl(args.endpoint.url);\n await validateResolvedIp(args.endpoint.url);\n\n let attempt = 0;\n const maxAttempts = 3;\n\n while (attempt < maxAttempts) {\n attempt += 1;\n const signature = signWebhookPayload(args.endpoint.secret, args.payload);\n\n try {\n const response = await this.fetchImpl(args.endpoint.url, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"x-commerce-signature\": signature,\n \"x-commerce-event\": args.eventName,\n },\n body: JSON.stringify(args.payload),\n signal: AbortSignal.timeout(10_000),\n });\n\n await this.deps.repository.createDelivery({\n endpointId: args.endpoint.id,\n eventName: args.eventName,\n payload: args.payload,\n statusCode: response.status,\n attemptCount: attempt,\n ...(response.ok ? { deliveredAt: new Date() } : {}),\n ...(!response.ok ? { failedAt: new Date() } : {}),\n ...(!response.ok && attempt < maxAttempts\n ? { nextRetryAt: new Date(Date.now() + 2 ** attempt * 1000) }\n : {}),\n });\n\n if (response.ok) return;\n } catch {\n await this.deps.repository.createDelivery({\n endpointId: args.endpoint.id,\n eventName: args.eventName,\n payload: args.payload,\n attemptCount: attempt,\n failedAt: new Date(),\n ...(attempt < maxAttempts\n ? { nextRetryAt: new Date(Date.now() + 2 ** attempt * 1000) }\n : {}),\n });\n }\n }\n }\n}\n",
|
|
121
|
+
"import { eq, and, desc, gte, lte } from \"drizzle-orm\";\nimport type { InferSelectModel } from \"drizzle-orm\";\nimport type { DrizzleDatabase } from \"../../kernel/database/drizzle-db\";\nimport type { TxContext } from \"../../kernel/database/tx-context\";\nimport type { HookContext } from \"../../kernel/hooks/types\";\nimport { resolveOrgId } from \"../../auth/org\";\nimport { auditLog } from \"./schema\";\n\nexport type AuditEntry = InferSelectModel<typeof auditLog>;\n\nexport interface RecordArgs {\n entityType: string;\n entityId: string;\n event: string;\n payload?: Record<string, unknown>;\n ctx: HookContext;\n}\n\nexport interface ListForEntityArgs {\n organizationId?: string;\n entityType: string;\n entityId: string;\n limit?: number;\n ctx?: TxContext;\n}\n\nexport interface ListArgs {\n organizationId?: string | undefined;\n entityType?: string | undefined;\n entityId?: string | undefined;\n event?: string | undefined;\n actorId?: string | undefined;\n from?: Date | undefined;\n to?: Date | undefined;\n limit?: number | undefined;\n}\n\nexport interface AuditService {\n record(args: RecordArgs): Promise<void>;\n listForEntity(args: ListForEntityArgs): Promise<AuditEntry[]>;\n list(args: ListArgs): Promise<AuditEntry[]>;\n}\n\nexport function createNullAuditService(): AuditService {\n const entries: AuditEntry[] = [];\n return {\n async record(args) {\n entries.push({\n id: crypto.randomUUID(),\n organizationId: resolveOrgId(args.ctx.actor),\n entityType: args.entityType,\n entityId: args.entityId,\n event: args.event,\n payload: args.payload ?? {},\n actorId: args.ctx.actor?.userId ?? null,\n actorType: args.ctx.actor != null ? \"user\" : null,\n requestId: args.ctx.requestId,\n createdAt: new Date(),\n });\n },\n async listForEntity(args) {\n return entries\n .filter(\n (e) =>\n e.entityType === args.entityType && e.entityId === args.entityId,\n )\n .sort(\n (a, b) => b.createdAt.getTime() - a.createdAt.getTime(),\n )\n .slice(0, args.limit ?? 50);\n },\n async list(args) {\n let result = entries;\n if (args.entityType) result = result.filter((e) => e.entityType === args.entityType);\n if (args.entityId) result = result.filter((e) => e.entityId === args.entityId);\n if (args.event) result = result.filter((e) => e.event === args.event);\n if (args.actorId) result = result.filter((e) => e.actorId === args.actorId);\n if (args.from) result = result.filter((e) => e.createdAt >= args.from!);\n if (args.to) result = result.filter((e) => e.createdAt <= args.to!);\n return result\n .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())\n .slice(0, args.limit ?? 50);\n },\n };\n}\n\nexport function createAuditService(db: DrizzleDatabase): AuditService {\n return {\n async record(args) {\n const { entityType, entityId, event, payload, ctx } = args;\n const dbOrTx =\n ctx.tx != null\n ? (ctx.tx as typeof db)\n : db;\n\n await dbOrTx.insert(auditLog).values({\n organizationId: resolveOrgId(ctx.actor),\n entityType,\n entityId,\n event,\n payload: payload ?? {},\n actorId: ctx.actor?.userId ?? null,\n actorType: ctx.actor != null ? \"user\" : null,\n requestId: ctx.requestId,\n });\n },\n\n async listForEntity(args) {\n const { organizationId, entityType, entityId, limit = 50, ctx } = args;\n const dbOrTx =\n ctx?.tx != null\n ? (ctx.tx as typeof db)\n : db;\n\n const conditions = [\n eq(auditLog.entityType, entityType),\n eq(auditLog.entityId, entityId),\n ];\n if (organizationId) {\n conditions.push(eq(auditLog.organizationId, organizationId));\n }\n\n return dbOrTx\n .select()\n .from(auditLog)\n .where(and(...conditions))\n .orderBy(desc(auditLog.createdAt))\n .limit(limit);\n },\n\n async list(args) {\n const conditions = [];\n if (args.organizationId) conditions.push(eq(auditLog.organizationId, args.organizationId));\n if (args.entityType) conditions.push(eq(auditLog.entityType, args.entityType));\n if (args.entityId) conditions.push(eq(auditLog.entityId, args.entityId));\n if (args.event) conditions.push(eq(auditLog.event, args.event));\n if (args.actorId) conditions.push(eq(auditLog.actorId, args.actorId));\n if (args.from) conditions.push(gte(auditLog.createdAt, args.from));\n if (args.to) conditions.push(lte(auditLog.createdAt, args.to));\n\n let query = db.select().from(auditLog).$dynamic();\n if (conditions.length > 0) {\n query = query.where(conditions.length === 1 ? conditions[0]! : and(...conditions));\n }\n\n return query\n .orderBy(desc(auditLog.createdAt))\n .limit(args.limit ?? 50);\n },\n };\n}\n",
|
|
122
|
+
"import type {\n CommerceConfig,\n MCPResource,\n MCPTool,\n} from \"../config/types\";\nimport { HookRegistry, type HookHandler } from \"../kernel/hooks/registry\";\nimport {\n createDatabaseConnection,\n type DatabaseAdapter,\n} from \"../kernel/database/adapter\";\nimport type { PluginDb } from \"../kernel/database/plugin-types\";\n\nimport { CatalogServiceImpl } from \"../modules/catalog/service\";\nimport { CatalogRepository } from \"../modules/catalog/repository\";\nimport { InventoryRepository } from \"../modules/inventory/repository\";\nimport { CartRepository } from \"../modules/cart/repository\";\nimport { OrdersRepository } from \"../modules/orders/repository\";\nimport { CustomersRepository } from \"../modules/customers/repository\";\nimport { PricingRepository } from \"../modules/pricing/repository\";\nimport { PromotionsRepository } from \"../modules/promotions/repository\";\nimport { FulfillmentRepository } from \"../modules/fulfillment/repository\";\nimport { WebhooksRepository } from \"../modules/webhooks/repository\";\nimport { MediaRepository } from \"../modules/media/repository\";\nimport type { DrizzleDatabase } from \"../kernel/database/drizzle-db\";\nimport { InventoryService } from \"../modules/inventory/service\";\nimport { MediaService } from \"../modules/media/service\";\nimport { CartService } from \"../modules/cart/service\";\nimport { OrderService } from \"../modules/orders/service\";\nimport { PaymentsService } from \"../modules/payments/service\";\nimport { FulfillmentService } from \"../modules/fulfillment/service\";\nimport { CustomerService } from \"../modules/customers/service\";\nimport { WebhookService } from \"../modules/webhooks/service\";\nimport { AnalyticsService } from \"../modules/analytics/service\";\nimport { DrizzleAnalyticsAdapter } from \"../modules/analytics/drizzle-adapter\";\nimport { BUILTIN_ANALYTICS_MODELS } from \"../modules/analytics/models\";\nimport { PricingService } from \"../modules/pricing/service\";\nimport { PromotionService } from \"../modules/promotions/service\";\nimport { TaxService } from \"../modules/tax/service\";\nimport { ShippingService } from \"../modules/shipping/service\";\nimport { SearchService } from \"../modules/search/service\";\nimport { WebhookDeliveryWorker } from \"../modules/webhooks/worker\";\nimport {\n createAuditService,\n type AuditService,\n} from \"../modules/audit/service\";\nimport { OrganizationService } from \"../modules/organization/service\";\nimport { createLogger } from \"../utils/logger\";\nimport { withTiming } from \"../kernel/service-timing\";\nimport { extendOrderStateMachine } from \"../kernel/state-machine/machine\";\nimport { DEFAULT_ORG_ID } from \"../auth/org\";\nimport { deliverWebhooks } from \"../modules/webhooks/hook\";\n// Analytics event recording hooks removed (RFC-006): source tables ARE the events.\n// The DrizzleAnalyticsAdapter queries orders/inventory directly via SQL.\nimport { syncToSearchIndex } from \"../modules/search/hooks\";\nimport { auditHooks } from \"../modules/audit/hooks\";\nimport { sendOrderStatusEmail } from \"../hooks/order-emails\";\nimport { DrizzleJobsAdapter } from \"../kernel/jobs/drizzle-adapter\";\n\nexport interface WebhookDeliveryPayload {\n endpoint: { id: string; url: string; secret: string };\n eventName: string;\n payload: unknown;\n}\n\nexport interface Kernel {\n config: CommerceConfig;\n hooks: HookRegistry;\n database: DatabaseAdapter;\n services: {\n catalog: CatalogServiceImpl;\n inventory: InventoryService;\n media: MediaService;\n cart: CartService;\n orders: OrderService;\n payments: PaymentsService;\n fulfillment: FulfillmentService;\n customers: CustomerService;\n webhooks: WebhookService & {\n enqueueDelivery(payload: WebhookDeliveryPayload): Promise<void>;\n };\n analytics: AnalyticsService;\n pricing: PricingService;\n promotions: PromotionService;\n tax: TaxService;\n shipping: ShippingService;\n search: SearchService;\n audit: AuditService;\n email: CommerceConfig[\"email\"];\n organization: OrganizationService;\n };\n mcpTools: MCPTool[];\n mcpResources: MCPResource[];\n logger: ReturnType<typeof createLogger>;\n getMCPActor(): {\n type: \"api_key\";\n userId: string;\n email: null;\n name: string;\n vendorId: null;\n organizationId: string;\n role: string;\n permissions: string[];\n };\n}\n\nconst requiredServiceKeys = [\n \"catalog\",\n \"inventory\",\n \"media\",\n \"cart\",\n \"orders\",\n \"payments\",\n \"fulfillment\",\n \"customers\",\n \"webhooks\",\n \"analytics\",\n \"pricing\",\n \"promotions\",\n \"tax\",\n \"shipping\",\n \"search\",\n \"audit\",\n] as const satisfies Array<keyof Kernel[\"services\"]>;\n\nfunction assertServicesReady(\n services: Partial<Kernel[\"services\"]>,\n): asserts services is Kernel[\"services\"] {\n for (const key of requiredServiceKeys) {\n if (services[key] === undefined) {\n throw new Error(`Kernel service \"${String(key)}\" was not initialized.`);\n }\n }\n}\n\nfunction registerConfiguredHooks(\n config: CommerceConfig,\n hooks: HookRegistry,\n): void {\n for (const [entityType, entityConfig] of Object.entries(\n config.entities ?? {},\n )) {\n const entityHooks = entityConfig.hooks ?? {};\n for (const [hookName, handlers] of Object.entries(entityHooks)) {\n hooks.registerConfigHooks(\n `catalog.${entityType}.${hookName}`,\n handlers ?? [],\n );\n }\n }\n\n for (const [moduleName, moduleConfig] of [\n [\"cart\", config.cart],\n [\"checkout\", config.checkout],\n [\"orders\", config.orders],\n [\"inventory\", config.inventory],\n ] as const) {\n const hooksObject = moduleConfig?.hooks;\n if (!hooksObject) continue;\n for (const [hookName, handlers] of Object.entries(hooksObject)) {\n const normalizedHandlers: HookHandler[] = Array.isArray(handlers)\n ? (handlers as unknown as HookHandler[])\n : [];\n hooks.registerConfigHooks(\n `${moduleName}.${hookName}`,\n normalizedHandlers,\n );\n }\n }\n\n // Webhook delivery (async via job queue) — 14 event types\n hooks.append(\"orders.afterCreate\", deliverWebhooks);\n hooks.append(\"orders.afterStatusChange\", deliverWebhooks);\n hooks.append(\"orders.afterStatusChange\", sendOrderStatusEmail as (...args: unknown[]) => unknown);\n hooks.append(\"catalog.afterCreate\", deliverWebhooks);\n hooks.append(\"catalog.afterUpdate\", deliverWebhooks);\n hooks.append(\"catalog.afterDelete\", deliverWebhooks);\n hooks.append(\"inventory.afterAdjust\", deliverWebhooks);\n hooks.append(\"customers.afterCreate\", deliverWebhooks);\n hooks.append(\"customers.afterUpdate\", deliverWebhooks);\n hooks.append(\"pricing.afterCreate\", deliverWebhooks);\n hooks.append(\"pricing.afterUpdate\", deliverWebhooks);\n hooks.append(\"promotions.afterCreate\", deliverWebhooks);\n hooks.append(\"promotions.afterUpdate\", deliverWebhooks);\n hooks.append(\"fulfillment.afterCreate\", deliverWebhooks);\n hooks.append(\"cart.afterAddItem\", deliverWebhooks);\n\n // Analytics: no event recording hooks needed (RFC-006).\n // The DrizzleAnalyticsAdapter queries source tables directly via SQL.\n\n // Search index sync\n hooks.append(\"catalog.afterCreate\", syncToSearchIndex);\n hooks.append(\"catalog.afterUpdate\", syncToSearchIndex);\n\n // Auto-audit — records every create/update/delete across all modules\n for (const [key, handler] of Object.entries(auditHooks)) {\n hooks.append(key, handler);\n }\n}\n\nexport function createKernel(config: CommerceConfig): Kernel {\n const hooks = new HookRegistry();\n const logger = createLogger(\"kernel\");\n hooks.setLogger(logger as unknown as { error: (obj: Record<string, unknown>, msg: string) => void });\n\n if (!config.storage) {\n throw new Error(\n \"Storage adapter is required. Configure `storage` in defineConfig (for example: localStorageAdapter for development, or s3StorageAdapter/r2StorageAdapter for object storage).\",\n );\n }\n\n const database = createDatabaseConnection({\n adapter: config.databaseAdapter ?? {\n provider: config.database.provider,\n db: {},\n async transaction<T>(fn: (tx: unknown) => Promise<T>): Promise<T> {\n return fn({});\n },\n },\n });\n const mcpTools: MCPTool[] = [];\n const mcpResources: MCPResource[] = [];\n\n const services: Partial<Kernel[\"services\"]> = {\n email: config.email,\n organization: new OrganizationService(database.db),\n };\n\n const serviceContainer = services as Record<string, unknown>;\n\n // Expose database on service container so plugin hooks can access it\n serviceContainer.database = database;\n\n const db = database.db as DrizzleDatabase;\n\n // Expose jobs adapter on service container so plugins can enqueue background work\n const jobsAdapter = new DrizzleJobsAdapter(db, new Map());\n serviceContainer.jobs = jobsAdapter;\n\n const pricingRepository = new PricingRepository(db);\n const promotionsRepository = new PromotionsRepository(db);\n\n services.tax = new TaxService({ adapter: config.tax?.adapter });\n services.payments = new PaymentsService(config.payments);\n\n const customersRepository = new CustomersRepository(db);\n services.customers = new CustomerService({\n repository: customersRepository,\n });\n\n const webhooksRepository = new WebhooksRepository(db);\n const webhookWorker = new WebhookDeliveryWorker({\n repository: webhooksRepository,\n });\n services.webhooks = Object.assign(\n new WebhookService({\n repository: webhooksRepository,\n }),\n {\n async enqueueDelivery(payload: WebhookDeliveryPayload) {\n await webhookWorker.deliver(payload);\n },\n },\n );\n\n const inventoryRepository = new InventoryRepository(db);\n services.inventory = new InventoryService({\n repository: inventoryRepository,\n hooks,\n config,\n services: serviceContainer,\n database,\n });\n\n const catalogRepository = new CatalogRepository(db);\n services.catalog = new CatalogServiceImpl({\n repository: catalogRepository,\n hooks,\n config,\n services: serviceContainer,\n });\n\n services.search = new SearchService({\n catalogRepository: catalogRepository,\n ...(config.search?.adapter ? { adapter: config.search.adapter } : {}),\n ...(config.search?.defaultFacets\n ? { defaultFacets: config.search.defaultFacets }\n : {}),\n });\n\n const cartRepository = new CartRepository(db);\n services.cart = new CartService({\n repository: cartRepository,\n catalogRepository: catalogRepository,\n hooks,\n config,\n services: serviceContainer,\n });\n\n const ordersRepository = new OrdersRepository(db);\n services.orders = new OrderService({\n repository: ordersRepository,\n hooks,\n services: serviceContainer,\n kernel: { database: database as { db: PluginDb } },\n ...(config.orders?.customTransitions\n ? { stateMachine: extendOrderStateMachine(config.orders.customTransitions) }\n : {}),\n });\n\n const fulfillmentRepository = new FulfillmentRepository(db);\n services.fulfillment = new FulfillmentService({\n repository: fulfillmentRepository,\n ordersRepository: ordersRepository,\n inventoryService: services.inventory,\n });\n\n services.pricing = new PricingService({\n repository: pricingRepository,\n catalogRepository: catalogRepository,\n });\n\n services.promotions = new PromotionService({\n repository: promotionsRepository,\n catalogRepository: catalogRepository,\n ordersRepository: ordersRepository,\n });\n\n // AnalyticsService — always uses DrizzleAnalyticsAdapter (direct SQL).\n // Plugins add their own models via the analyticsModels manifest slot.\n const analyticsAdapter = new DrizzleAnalyticsAdapter(db);\n for (const model of BUILTIN_ANALYTICS_MODELS) {\n analyticsAdapter.registerModel(model);\n }\n services.analytics = new AnalyticsService({\n adapter: analyticsAdapter,\n config,\n });\n\n services.shipping = new ShippingService({\n config,\n catalogRepository: catalogRepository,\n });\n\n const mediaRepository = new MediaRepository(db);\n services.media = new MediaService({\n repository: mediaRepository,\n catalogRepository: catalogRepository,\n storage: config.storage,\n });\n\n services.audit = createAuditService(db);\n\n assertServicesReady(services);\n\n // Service method observability: wrap each service in a timing proxy\n // that logs slow calls (>100ms) and failed calls with duration.\n // Disabled in test environment to avoid noisy logs.\n if (process.env.NODE_ENV !== \"test\") {\n const timedLogger = logger as unknown as { info: (o: Record<string, unknown>, m: string) => void; error: (o: Record<string, unknown>, m: string) => void };\n const serviceKeys = Object.keys(services) as Array<keyof typeof services>;\n for (const key of serviceKeys) {\n const svc = services[key];\n if (svc && typeof svc === \"object\" && key !== \"email\") {\n (services as Record<string, unknown>)[key] = withTiming(\n svc as object,\n key,\n timedLogger,\n );\n }\n }\n }\n\n registerConfiguredHooks(config, hooks);\n\n const kernel: Kernel = {\n config,\n hooks,\n database,\n services,\n mcpTools,\n mcpResources,\n logger,\n getMCPActor() {\n return {\n type: \"api_key\",\n userId: \"mcp-agent\",\n email: null,\n name: \"MCP Agent\",\n vendorId: null,\n organizationId: DEFAULT_ORG_ID,\n role: \"ai_agent\",\n permissions: config.auth?.roles?.ai_agent?.permissions ?? [\n \"catalog:read\",\n \"catalog:create\",\n \"inventory:read\",\n \"inventory:adjust\",\n \"orders:read\",\n \"cart:create\",\n \"cart:update\",\n \"mcp:access\",\n ],\n };\n },\n };\n\n // Register plugin hooks from config.hooks flat map\n for (const [key, handlers] of Object.entries(config.hooks ?? {})) {\n for (const handler of handlers) {\n hooks.append(key, handler as HookHandler);\n }\n }\n\n // Register plugin analytics models from config.analytics.models\n for (const model of config.analytics?.models ?? []) {\n services.analytics.registerModel(model);\n }\n\n return kernel;\n}\n",
|
|
123
|
+
"/**\n * Service method observability via ES Proxy.\n *\n * Wraps a service object so that every async method call is timed.\n * Slow calls (above threshold) are logged with service name, method name,\n * and duration. Failed calls always log with the error.\n *\n * Usage at kernel boot:\n * services.inventory = withTiming(inventoryService, \"inventory\", logger);\n * services.catalog = withTiming(catalogService, \"catalog\", logger);\n *\n * Produces log entries like:\n * { service: \"inventory\", method: \"adjust\", durationMs: 245 } \"slow service call\"\n * { service: \"catalog\", method: \"create\", durationMs: 12, err: ... } \"service call failed\"\n *\n * Only wraps own methods (not inherited). Synchronous property access\n * (e.g., reading a field) passes through unchanged with zero overhead.\n */\n\ninterface TimingLogger {\n info(obj: Record<string, unknown>, msg: string): void;\n error(obj: Record<string, unknown>, msg: string): void;\n}\n\nexport function withTiming<T extends object>(\n service: T,\n serviceName: string,\n logger: TimingLogger,\n slowThresholdMs = 100,\n): T {\n return new Proxy(service, {\n get(target, prop, receiver) {\n const value = Reflect.get(target, prop, receiver);\n\n // Only wrap functions, skip symbols and non-function props\n if (typeof value !== \"function\" || typeof prop === \"symbol\") {\n return value;\n }\n\n // Skip internal/private-looking methods\n const methodName = String(prop);\n if (methodName.startsWith(\"_\")) return value;\n\n return function proxiedMethod(this: unknown, ...args: unknown[]) {\n const start = performance.now();\n\n // Call the original method\n let result: unknown;\n try {\n result = value.apply(target, args);\n } catch (err) {\n // Synchronous throw\n const durationMs = Math.round(performance.now() - start);\n logger.error(\n { service: serviceName, method: methodName, durationMs, err },\n `${serviceName}.${methodName} failed (${durationMs}ms)`,\n );\n throw err;\n }\n\n // If result is a promise, attach timing to its resolution\n if (result && typeof (result as Promise<unknown>).then === \"function\") {\n return (result as Promise<unknown>).then(\n (resolved) => {\n const durationMs = Math.round(performance.now() - start);\n if (durationMs > slowThresholdMs) {\n logger.info(\n { service: serviceName, method: methodName, durationMs },\n `${serviceName}.${methodName} slow (${durationMs}ms)`,\n );\n }\n return resolved;\n },\n (err) => {\n const durationMs = Math.round(performance.now() - start);\n logger.error(\n { service: serviceName, method: methodName, durationMs, err },\n `${serviceName}.${methodName} failed (${durationMs}ms)`,\n );\n throw err;\n },\n );\n }\n\n return result;\n };\n },\n });\n}\n",
|
|
124
|
+
"import type { AfterHook } from \"../../kernel/hooks/types\";\n\n/**\n * Webhook delivery hook — enqueues delivery jobs instead of blocking.\n *\n * Previously, this hook made synchronous HTTP calls to each webhook endpoint\n * inside the request handler, blocking the response for seconds if endpoints\n * were slow or down.\n *\n * Now it enqueues a background job per endpoint. The job runner delivers\n * asynchronously with retries. The HTTP response returns immediately.\n */\nexport const deliverWebhooks: AfterHook<unknown> = async ({ result, operation, context }) => {\n const eventName = `${String(context.context.moduleName ?? \"unknown\")}.${operation}`;\n const webhooksService = context.services.webhooks as {\n getEndpointsForEvent(event: string): Promise<{ ok: boolean; value: Array<{ id: string; url: string; secret: string }> }>;\n };\n\n const endpoints = await webhooksService.getEndpointsForEvent(eventName);\n if (!endpoints.ok) return;\n\n for (const endpoint of endpoints.value) {\n await context.jobs.enqueue(\"webhooks/deliver\", {\n endpointId: endpoint.id,\n endpointUrl: endpoint.url,\n endpointSecret: endpoint.secret,\n eventName,\n payload: result,\n }, {\n maxAttempts: 5,\n queue: \"webhooks\",\n });\n }\n};\n",
|
|
125
|
+
"import type { HookContext } from \"../../kernel/hooks/types\";\nimport type { SearchService } from \"./service\";\n\nexport async function syncToSearchIndex(args: {\n result: { id: string };\n context: HookContext;\n}): Promise<void> {\n const service = args.context.services.search as SearchService | undefined;\n if (!service) return;\n\n await service.syncEntity(args.result.id);\n}\n",
|
|
126
|
+
"import type { AfterHook } from \"../../kernel/hooks/types\";\nimport type { HookHandler } from \"../../kernel/hooks/registry\";\nimport type { AuditService } from \"./service\";\n\n/**\n * Creates an after-hook that records an audit entry for the operation.\n *\n * The audit entry is written using the same transaction context as the\n * business operation (via ctx.tx). If the operation rolls back, the\n * audit entry rolls back too.\n */\nfunction createAuditAfterHook(entityType: string, event: string): AfterHook<Record<string, unknown>> {\n return async ({ result, context }) => {\n const audit = context.services.audit as AuditService | undefined;\n if (!audit?.record) return;\n\n const entityId = (result as { id?: string })?.id ?? \"unknown\";\n\n await audit.record({\n entityType,\n entityId,\n event,\n payload: safePayload(result),\n ctx: context,\n });\n };\n}\n\n/**\n * Strips the result to a safe subset for audit logging.\n * Avoids storing sensitive fields or excessively large payloads.\n */\nfunction safePayload(result: unknown): Record<string, unknown> {\n if (result == null || typeof result !== \"object\") return {};\n const obj = result as Record<string, unknown>;\n\n // Shallow copy, exclude fields that could be huge\n const safe: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n // Skip binary data, nested arrays > 10 items, and known sensitive fields\n if (key === \"password\" || key === \"secret\" || key === \"bankAccount\") continue;\n if (Array.isArray(value) && value.length > 10) {\n safe[key] = `[${value.length} items]`;\n continue;\n }\n safe[key] = value;\n }\n return safe;\n}\n\n/**\n * All audit hooks, keyed by hook registration key.\n * Registered in kernel boot via hooks.append().\n */\nexport const auditHooks: Record<string, HookHandler> = {\n // Catalog\n \"catalog.afterCreate\": createAuditAfterHook(\"catalog_entity\", \"created\") as HookHandler,\n \"catalog.afterUpdate\": createAuditAfterHook(\"catalog_entity\", \"updated\") as HookHandler,\n\n // Orders\n \"orders.afterCreate\": createAuditAfterHook(\"order\", \"created\") as HookHandler,\n \"orders.afterStatusChange\": createAuditAfterHook(\"order\", \"status_changed\") as HookHandler,\n\n // Inventory\n \"inventory.afterAdjust\": createAuditAfterHook(\"inventory\", \"adjusted\") as HookHandler,\n\n // Customers\n \"customers.afterCreate\": createAuditAfterHook(\"customer\", \"created\") as HookHandler,\n \"customers.afterUpdate\": createAuditAfterHook(\"customer\", \"updated\") as HookHandler,\n\n // Pricing\n \"pricing.afterCreate\": createAuditAfterHook(\"price\", \"created\") as HookHandler,\n \"pricing.afterUpdate\": createAuditAfterHook(\"price\", \"updated\") as HookHandler,\n\n // Promotions\n \"promotions.afterCreate\": createAuditAfterHook(\"promotion\", \"created\") as HookHandler,\n \"promotions.afterUpdate\": createAuditAfterHook(\"promotion\", \"updated\") as HookHandler,\n};\n",
|
|
127
|
+
"/**\n * Order lifecycle email notifications.\n *\n * Sends emails on status changes: confirmed, fulfilled, cancelled, refunded.\n * Registered as an orders.afterStatusChange hook.\n */\n\nimport type { AfterHook } from \"../kernel/hooks/types\";\n\ninterface StatusChangeResult {\n orderId: string;\n customerId?: string | null;\n newStatus: string;\n previousStatus: string;\n}\n\nexport const sendOrderStatusEmail: AfterHook<StatusChangeResult> = async ({\n result,\n context,\n}) => {\n const email = context.services.email as\n | { send(input: { template: string; to: string; data?: Record<string, unknown> }): Promise<void> }\n | undefined;\n\n if (!email?.send) return;\n\n // Only send for customer-facing status changes\n const notifiableStatuses = [\"confirmed\", \"processing\", \"fulfilled\", \"cancelled\", \"refunded\"];\n if (!notifiableStatuses.includes(result.newStatus)) return;\n\n // Look up customer email\n const customerId = result.customerId;\n if (!customerId) return;\n\n const customers = context.services.customers as\n | { getByUserId(id: string, actor?: unknown): Promise<{ ok: boolean; value?: { email?: string | null } }> }\n | undefined;\n\n if (!customers) return;\n\n try {\n const customer = await customers.getByUserId(customerId, context.actor);\n if (!customer.ok || !customer.value?.email) return;\n\n await email.send({\n template: \"order-status-change\",\n to: customer.value.email,\n data: {\n orderId: result.orderId,\n newStatus: result.newStatus,\n previousStatus: result.previousStatus,\n },\n });\n } catch (err) {\n // Email failure must not break the order flow\n context.logger.warn(\"Order status email failed\", {\n orderId: result.orderId,\n newStatus: result.newStatus,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n};\n",
|
|
128
|
+
"import { eq, and } from \"drizzle-orm\";\nimport type { DrizzleDatabase } from \"../database/drizzle-db\";\nimport type { TaskDefinition } from \"./types\";\nimport type { JobsAdapter, EnqueueOptions } from \"./adapter\";\nimport { DEFAULT_ORG_ID } from \"../../auth/org\";\nimport { commerceJobs } from \"./schema\";\n\n/**\n * PostgreSQL-backed job queue adapter using the application's own database.\n * Stores jobs in the `commerce_jobs` table. Supports concurrency keys\n * and supersede semantics for deduplication.\n */\nexport class DrizzleJobsAdapter implements JobsAdapter {\n constructor(\n private db: DrizzleDatabase,\n private tasks: Map<string, TaskDefinition>,\n ) {}\n\n async enqueue(\n taskSlug: string,\n input: Record<string, unknown>,\n options?: EnqueueOptions,\n ): Promise<string> {\n // If supersedes is set, delete existing pending jobs with the same concurrency key\n if (options?.concurrencyKey && options.supersedes) {\n await this.db\n .delete(commerceJobs)\n .where(\n and(\n eq(commerceJobs.concurrencyKey, options.concurrencyKey),\n eq(commerceJobs.status, \"pending\"),\n ),\n );\n }\n\n // Look up task definition for default retry config\n const task = this.tasks.get(taskSlug);\n const maxAttempts =\n options?.maxAttempts ?? task?.retries?.attempts ?? 1;\n\n const rows = await this.db\n .insert(commerceJobs)\n .values({\n organizationId: options?.organizationId ?? DEFAULT_ORG_ID,\n taskSlug,\n input,\n queue: options?.queue ?? \"default\",\n maxAttempts,\n waitUntil: options?.delayMs\n ? new Date(Date.now() + options.delayMs)\n : null,\n concurrencyKey: options?.concurrencyKey ?? null,\n })\n .returning({ id: commerceJobs.id });\n\n return rows[0]!.id;\n }\n}\n",
|
|
129
|
+
"import type { Actor } from \"../auth/types\";\nimport type { CommerceConfig } from \"../config/types\";\nimport type { Kernel } from \"./kernel\";\nimport { createKernel } from \"./kernel\";\nimport { ensureDefaultOrg } from \"../auth/org\";\nimport { createAuth, type AuthInstance } from \"../auth/setup\";\nimport { createLogger, type Logger } from \"./logger\";\nimport { createLocalAPI, type CommerceLocalAPI, type LocalAPIOptions } from \"../kernel/local-api\";\n\n/**\n * The commerce instance returned by `createCommerce()`.\n *\n * This is the headless, framework-agnostic entry point.\n * No HTTP server, no Hono — just typed services and a local API.\n *\n * ## Usage with Next.js App Router:\n *\n * ```typescript\n * // lib/commerce.ts\n * import { createCommerce } from \"@unifiedcommerce/core\";\n * import config from \"../commerce.config\";\n *\n * export const commerce = await createCommerce(config);\n *\n * // app/products/page.tsx (Server Component)\n * import { commerce } from \"@/lib/commerce\";\n *\n * export default async function ProductsPage() {\n * const products = await commerce.api.catalog.list({ limit: 20 });\n * if (!products.ok) return <div>Error</div>;\n * return <ProductGrid items={products.value.items} />;\n * }\n * ```\n *\n * ## Usage with TanStack Start:\n *\n * ```typescript\n * // app/routes/products.tsx\n * import { createServerFn } from \"@tanstack/start\";\n * import { commerce } from \"../lib/commerce\";\n *\n * const getProducts = createServerFn(\"GET\", async () => {\n * return commerce.api.catalog.list({ limit: 20 });\n * });\n * ```\n *\n * ## Usage with SvelteKit:\n *\n * ```typescript\n * // src/lib/server/commerce.ts\n * import { createCommerce } from \"@unifiedcommerce/core\";\n * import config from \"./commerce.config\";\n * export const commerce = await createCommerce(config);\n *\n * // src/routes/products/+page.server.ts\n * import { commerce } from \"$lib/server/commerce\";\n * export async function load() {\n * const products = await commerce.api.catalog.list({ limit: 20 });\n * return { products: products.ok ? products.value : { items: [] } };\n * }\n * ```\n */\nexport interface CommerceInstance {\n /** Proxy-based local API — auto-injects actor/tx to every service call */\n api: CommerceLocalAPI;\n\n /** Raw kernel for advanced usage (hooks, database, config) */\n kernel: Kernel;\n\n /** Drizzle database instance for direct queries */\n db: unknown;\n\n /** Auth instance (Better Auth) for session management */\n auth: AuthInstance;\n\n /** Logger */\n logger: Logger;\n\n /**\n * Create a scoped API for a specific user/actor.\n * Use this in authenticated routes to scope data access.\n *\n * ```typescript\n * // In a Next.js server action:\n * const userApi = commerce.withActor({\n * type: \"user\", userId: session.userId, ...\n * });\n * const orders = await userApi.orders.list({ limit: 10 });\n * // Only returns orders for this user's org\n * ```\n */\n withActor(actor: Actor): CommerceLocalAPI;\n\n /**\n * Create a scoped API within a database transaction.\n *\n * ```typescript\n * await commerce.kernel.database.transaction(async (tx) => {\n * const txApi = commerce.withTransaction(tx, actor);\n * await txApi.inventory.adjust({ entityId, adjustment: -1, reason: \"sold\" });\n * await txApi.orders.create({ ... });\n * });\n * ```\n */\n withTransaction(tx: unknown, actor?: Actor | null): CommerceLocalAPI;\n}\n\n/**\n * Create a headless commerce instance.\n *\n * This is the primary entry point for using UnifiedCommerce without an HTTP server.\n * It initializes the kernel, database, auth, and returns a local API that works\n * exactly like the REST API but without HTTP overhead.\n *\n * The Hono server (`createServer`) is optional — use it only when you need\n * a standalone HTTP API. For Next.js, TanStack Start, SvelteKit, Nuxt, etc.,\n * use `createCommerce()` directly.\n */\nexport async function createCommerce(\n config: CommerceConfig,\n): Promise<CommerceInstance> {\n const kernel = createKernel(config);\n await ensureDefaultOrg(kernel.database.db);\n const auth = createAuth(kernel.database, config);\n const logger = createLogger(config);\n\n // Default API: no actor (public access), no transaction\n const api = createLocalAPI(kernel);\n\n return {\n api,\n kernel,\n db: kernel.database.db,\n auth,\n logger,\n\n withActor(actor: Actor): CommerceLocalAPI {\n return createLocalAPI(kernel, { actor });\n },\n\n withTransaction(tx: unknown, actor?: Actor | null): CommerceLocalAPI {\n return createLocalAPI(kernel, { actor: actor ?? null, tx });\n },\n };\n}\n",
|
|
130
|
+
"import { drizzleAdapter } from \"@better-auth/drizzle-adapter\";\nimport { betterAuth } from \"better-auth\";\nimport type { Role } from \"better-auth/plugins/access\";\nimport { apiKey } from \"@better-auth/api-key\";\nimport { organization, twoFactor, phoneNumber } from \"better-auth/plugins\";\nimport type { CommerceConfig } from \"../config/types\";\nimport type { DatabaseAdapter } from \"../kernel/database/adapter\";\nimport * as authSchema from \"./auth-schema\";\n\ntype BetterAuthDbProvider = \"pg\" | \"mysql\" | \"sqlite\";\n\nfunction resolveAuthDbProvider(provider: string): BetterAuthDbProvider {\n if (\n provider === \"postgres\" ||\n provider === \"postgresql\" ||\n provider === \"pg\"\n ) {\n return \"pg\";\n }\n if (provider === \"mysql\") {\n return \"mysql\";\n }\n if (provider === \"sqlite\") {\n return \"sqlite\";\n }\n throw new Error(\n `Unsupported auth database provider \"${provider}\". Expected one of: postgres, mysql, sqlite.`,\n );\n}\n\ninterface AuthEmailPayload {\n user: {\n email: string;\n name: string | null;\n };\n url: string;\n}\n\nexport interface AuthInstance {\n handler(request: Request): Promise<Response>;\n api: {\n getSession(input: { headers: Headers }): Promise<unknown>;\n verifyApiKey?: (input: { key: string }) => Promise<{\n userId: string;\n name?: string | null;\n permissions?: string[];\n } | null>;\n createApiKey?: (input: {\n userId: string;\n name?: string;\n permissions?: string[];\n }) => Promise<{ key: string; id: string }>;\n /** Allow access to other Better Auth API methods added by plugins */\n [key: string]: unknown;\n };\n options?: Record<string, unknown>;\n $context?: Promise<unknown>;\n}\n\nexport function createAuth(\n db: DatabaseAdapter,\n config: CommerceConfig,\n): AuthInstance {\n const plugins: Array<\n | ReturnType<typeof organization>\n | ReturnType<typeof twoFactor>\n | ReturnType<typeof apiKey>\n | ReturnType<typeof phoneNumber>\n > = [\n organization({\n roles: (config.auth?.roles ?? {}) as unknown as Record<\n string,\n Role | undefined\n >,\n }),\n ];\n\n if (config.auth?.twoFactor?.enabled) {\n plugins.push(twoFactor({ issuer: config.storeName ?? \"UnifiedCommerce\" }));\n }\n\n if (config.auth?.apiKeys?.enabled) {\n plugins.push(apiKey());\n }\n\n if (config.auth?.phoneAuth) {\n plugins.push(phoneNumber({\n sendOTP: config.auth.phoneAuth.sendOTP,\n verifyOTP: config.auth.phoneAuth.verifyOTP,\n otpLength: config.auth.phoneAuth.otpLength ?? 6,\n expiresIn: config.auth.phoneAuth.expiresIn ?? 300,\n signUpOnVerification: config.auth.phoneAuth.signUpOnVerification ?? {\n getTempEmail: (phone: string) => `${phone.replace(/\\+/g, \"\")}@phone.local`,\n },\n }));\n }\n\n // API key support can be attached via external plugin package in newer better-auth versions.\n\n try {\n const auth = betterAuth({\n database: drizzleAdapter(db.db as Record<string, unknown>, {\n provider: resolveAuthDbProvider(db.provider),\n schema: authSchema,\n }),\n trustedOrigins: config.auth?.trustedOrigins ?? [],\n emailAndPassword: {\n enabled: true,\n requireEmailVerification: config.auth?.requireEmailVerification ?? true,\n sendResetPassword: async ({ user, url }: AuthEmailPayload) => {\n if (!config.email) return;\n await config.email.send({\n template: \"password-reset\",\n to: user.email,\n data: { resetUrl: url, userName: user.name },\n });\n },\n sendVerificationEmail: async ({ user, url }: AuthEmailPayload) => {\n if (!config.email) return;\n await config.email.send({\n template: \"email-verification\",\n to: user.email,\n data: { verifyUrl: url, userName: user.name },\n });\n },\n },\n socialProviders: config.auth?.socialProviders ?? {},\n session: {\n expiresIn: config.auth?.sessionDuration ?? 60 * 60 * 24 * 7,\n updateAge: 60 * 60 * 24,\n cookieCache: {\n enabled: true,\n maxAge: 60 * 5, // 5 minute cookie cache for performance\n },\n },\n advanced: {\n cookiePrefix: \"uc\",\n useSecureCookies: process.env.NODE_ENV === \"production\",\n },\n plugins,\n user: {\n additionalFields: {\n vendorId: { type: \"string\", required: false },\n posOperatorPin: { type: \"string\", required: false },\n },\n },\n });\n // Better Auth's plugin-extended return type doesn't structurally overlap\n // with our simplified AuthInstance interface (e.g., verifyApiKey expects\n // { body: { key } } internally but we expose { key } for ergonomics).\n // The double-cast is intentional and unavoidable without forking the types.\n return auth as unknown as AuthInstance;\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown better-auth initialization error.\";\n throw new Error(`Failed to initialize authentication: ${message}`);\n }\n}\n",
|
|
131
|
+
"import pino from \"pino\";\nimport type { CommerceConfig } from \"../config/types\";\n\nexport type Logger = pino.Logger;\n\n/**\n * Create a structured JSON logger for the commerce engine.\n *\n * Automatically redacts sensitive fields (authorization, password, token, etc.)\n * from all log output. Uses Pino for high-performance, newline-delimited JSON.\n */\nexport function createLogger(config: CommerceConfig): Logger {\n return pino({\n level: config.logLevel ?? \"info\",\n redact: {\n paths: [\n \"req.headers.authorization\",\n \"req.headers.cookie\",\n \"*.password\",\n \"*.secret\",\n \"*.apiKey\",\n \"*.creditCard\",\n \"*.token\",\n \"*.apiToken\",\n ],\n censor: \"[REDACTED]\",\n },\n serializers: {\n req: pino.stdSerializers.req,\n err: pino.stdSerializers.err,\n },\n formatters: {\n level: (label) => ({ level: label }),\n },\n });\n}\n",
|
|
132
|
+
"import type { Actor } from \"../auth/types\";\nimport type { Kernel } from \"../runtime/kernel\";\nimport type { TxContext } from \"./database/tx-context\";\n\n/**\n * Proxy-based Local API — the Payload-style programmatic interface.\n *\n * Automatically exposes EVERY service on `kernel.services` (core + plugins)\n * without hardcoding method signatures. Uses a Proxy to intercept property\n * access and wrap each service method to auto-inject `actor` and `txCtx`.\n *\n * ## Usage in Next.js / TanStack Start / SvelteKit:\n *\n * ```typescript\n * import { createCommerce } from \"@unifiedcommerce/core\";\n * import config from \"./commerce.config\";\n *\n * const commerce = await createCommerce(config);\n *\n * // Server action / loader — no HTTP round-trip\n * const products = await commerce.api.catalog.list({ limit: 10 });\n * const order = await commerce.api.orders.getById(\"order-123\");\n *\n * // Plugin services are automatically available\n * const balance = await commerce.api.giftCards.checkBalance(\"CARD-CODE\");\n * const points = await commerce.api.loyalty.redeemPoints(\"org\", \"cust\", 100);\n * ```\n *\n * ## Usage from a hook:\n *\n * ```typescript\n * const api = createLocalAPI(kernel, { actor, tx });\n * const product = await api.catalog.getById(\"prod-123\");\n * ```\n *\n * ## How it works:\n *\n * 1. `api.catalog` → Proxy intercepts, finds `kernel.services.catalog`\n * 2. `api.catalog.getById(id)` → Proxy intercepts method call\n * 3. Wraps the call: `kernel.services.catalog.getById(id, actor, txCtx)`\n * 4. Returns the result directly — no HTTP, no serialization\n *\n * The Proxy auto-appends `actor` and `txCtx` to every method call.\n * Service methods that accept `(actor, ctx)` as the last two params\n * get them injected automatically. Methods that don't accept them\n * still work — extra args are harmlessly ignored by JavaScript.\n */\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\n/** Options for creating a local API instance */\nexport interface LocalAPIOptions {\n actor?: Actor | null;\n tx?: unknown;\n requestId?: string;\n}\n\n/**\n * Maps a service type to strip actor/txCtx params from each method.\n * Plugin authors get clean autocomplete: `api.catalog.create(input)`\n * instead of `api.catalog.create(input, actor, txCtx)`.\n */\ntype CleanService<T> = {\n [K in keyof T]: T[K] extends (...args: infer _A) => infer R\n ? (...args: unknown[]) => R\n : T[K];\n};\n\n/** The full local API type — all kernel services with cleaned signatures */\nexport type CommerceLocalAPI<\n TServices extends Record<string, unknown> = Kernel[\"services\"],\n> = {\n [K in keyof TServices]: TServices[K] extends Record<string, unknown>\n ? CleanService<TServices[K]>\n : TServices[K];\n};\n\n// ─── Implementation ─────────────────────────────────────────────────────────\n\nconst SERVICE_METHOD_CACHE = new WeakMap<object, Map<string, Function>>();\n\n/**\n * Create a proxy-based local API over kernel services.\n * Every service method gets `actor` and `txCtx` auto-injected.\n */\nexport function createLocalAPI(\n kernel: Kernel,\n options: LocalAPIOptions = {},\n): CommerceLocalAPI {\n const actor = options.actor ?? null;\n const txCtx: TxContext | undefined =\n options.tx != null\n ? ({\n tx: options.tx,\n actor,\n requestId: options.requestId ?? crypto.randomUUID(),\n } as TxContext)\n : undefined;\n\n // Top-level proxy: intercept service access (e.g., api.catalog, api.giftCards)\n return new Proxy(kernel.services as unknown as CommerceLocalAPI, {\n get(target, serviceName: string) {\n const service = (target as Record<string, unknown>)[serviceName];\n\n // Non-object services (e.g., email config) — return as-is\n if (service == null || typeof service !== \"object\") {\n return service;\n }\n\n // Method-level proxy: intercept method calls on the service\n return new Proxy(service, {\n get(svcTarget, methodName: string) {\n const method = (svcTarget as Record<string, unknown>)[methodName];\n\n if (typeof method !== \"function\") {\n return method;\n }\n\n // Check cache to avoid re-creating wrapper functions\n let methodCache = SERVICE_METHOD_CACHE.get(svcTarget as object);\n if (!methodCache) {\n methodCache = new Map();\n SERVICE_METHOD_CACHE.set(svcTarget as object, methodCache);\n }\n\n const cacheKey = `${methodName}:${actor?.userId ?? \"null\"}`;\n let cached = methodCache.get(cacheKey);\n if (cached) return cached;\n\n // Create wrapped method that auto-injects actor + txCtx\n cached = (...args: unknown[]) => {\n return (method as Function).call(svcTarget, ...args, actor, txCtx);\n };\n\n methodCache.set(cacheKey, cached);\n return cached;\n },\n });\n },\n });\n}\n\n// ─── Legacy Class API (backward compat) ─────────────────────────────────────\n\n/**\n * @deprecated Use `createLocalAPI(kernel, { actor, tx })` instead.\n * Kept for backward compatibility with existing hook code.\n */\nexport class LocalAPI {\n private _proxy: CommerceLocalAPI;\n\n constructor(\n ctx: { actor: Actor | null; tx: unknown; requestId: string },\n kernel: Kernel,\n ) {\n this._proxy = createLocalAPI(kernel, {\n actor: ctx.actor,\n tx: ctx.tx,\n requestId: ctx.requestId,\n });\n }\n\n get orders() { return this._proxy.orders; }\n get catalog() { return this._proxy.catalog; }\n get cart() { return this._proxy.cart; }\n get inventory() { return this._proxy.inventory; }\n get customers() { return this._proxy.customers; }\n get pricing() { return this._proxy.pricing; }\n get promotions() { return this._proxy.promotions; }\n get media() { return this._proxy.media; }\n get shipping() { return this._proxy.shipping; }\n get search() { return this._proxy.search; }\n get webhooks() { return this._proxy.webhooks; }\n get fulfillment() { return this._proxy.fulfillment; }\n get payments() { return this._proxy.payments; }\n get analytics() { return this._proxy.analytics; }\n get tax() { return this._proxy.tax; }\n get audit() { return this._proxy.audit; }\n get organization() { return this._proxy.organization; }\n\n /** Access any service (including plugins) by name */\n service(name: string) {\n return (this._proxy as Record<string, unknown>)[name];\n }\n}\n",
|
|
133
|
+
"import type { Logger } from \"./logger\";\n\n/**\n * Sets up graceful shutdown handlers for SIGTERM and SIGINT.\n *\n * On signal:\n * 1. Stops accepting new connections\n * 2. Runs cleanup (close DB pool, flush logs)\n * 3. Force-exits after timeout if cleanup hangs\n */\nexport function setupGracefulShutdown(opts: {\n cleanup: () => Promise<void>;\n logger: Logger;\n timeoutMs?: number;\n}): void {\n const { cleanup, logger, timeoutMs = 30_000 } = opts;\n let isShuttingDown = false;\n\n async function shutdown(signal: string) {\n if (isShuttingDown) return;\n isShuttingDown = true;\n\n logger.info({ signal }, \"shutdown signal received, draining connections\");\n\n const forceTimer = setTimeout(() => {\n logger.error(\"shutdown timeout exceeded, forcing exit\");\n process.exit(1);\n }, timeoutMs);\n forceTimer.unref();\n\n try {\n await cleanup();\n logger.info(\"graceful shutdown complete\");\n process.exit(0);\n } catch (err) {\n logger.error({ err }, \"error during shutdown\");\n process.exit(1);\n }\n }\n\n process.on(\"SIGTERM\", () => shutdown(\"SIGTERM\"));\n process.on(\"SIGINT\", () => shutdown(\"SIGINT\"));\n}\n",
|
|
134
|
+
"import { defineConfig } from \"../config/define-config\";\nimport type { CommerceConfig } from \"../config/types\";\nimport { Ok } from \"../kernel/result\";\nimport type { StorageAdapter } from \"../modules/media/adapter\";\n\nfunction createInMemoryStorageAdapter(): StorageAdapter {\n const files = new Map<string, { data: ArrayBuffer; contentType: string }>();\n const baseUrl = \"http://localhost:3000/test-assets\";\n\n return {\n providerId: \"test-memory-storage\",\n async upload(key, data, contentType) {\n const body =\n data instanceof ArrayBuffer\n ? data\n : await new Response(data).arrayBuffer();\n files.set(key, { data: body, contentType });\n return Ok({\n key,\n url: `${baseUrl}/${key}`,\n contentType,\n size: body.byteLength,\n });\n },\n async getUrl(key) {\n return Ok(`${baseUrl}/${key}`);\n },\n async getSignedUrl(key, expiresIn) {\n return Ok(`${baseUrl}/${key}?expiresIn=${expiresIn}`);\n },\n async delete(key) {\n files.delete(key);\n return Ok(undefined);\n },\n async list(prefix) {\n return Ok(\n Array.from(files.entries())\n .filter(([key]) => key.startsWith(prefix))\n .map(([key, file]) => ({\n key,\n url: `${baseUrl}/${key}`,\n contentType: file.contentType,\n size: file.data.byteLength,\n })),\n );\n },\n };\n}\n\nexport async function createTestConfig(\n overrides: Partial<CommerceConfig> = {},\n): Promise<CommerceConfig> {\n // Auto-provision PGlite when no databaseAdapter is provided\n if (!overrides.databaseAdapter) {\n const { createPGliteTestAdapter } = await import(\"./create-pglite-adapter\");\n const { adapter } = await createPGliteTestAdapter();\n overrides = { ...overrides, databaseAdapter: adapter };\n }\n\n return defineConfig({\n version: \"0.0.1-test\",\n storeName: \"Test Store\",\n database: {\n provider: \"postgresql\",\n },\n auth: {\n requireEmailVerification: false,\n apiKeys: { enabled: true, defaultPermissions: [\"catalog:read\"] },\n enableDevKey: true,\n devKey: \"dev-staff-key\",\n posPin: { enabled: true },\n roles: {\n owner: { permissions: [\"*:*\"] },\n admin: { permissions: [\"*:*\"] },\n staff: {\n permissions: [\n \"catalog:create\",\n \"catalog:update\",\n \"catalog:delete\",\n \"catalog:read\",\n \"inventory:adjust\",\n \"orders:create\",\n \"orders:read\",\n \"orders:update\",\n \"cart:create\",\n \"cart:update\",\n \"customers:update:self\",\n ],\n },\n ai_agent: {\n permissions: [\n \"catalog:read\",\n \"catalog:create\",\n \"inventory:read\",\n \"inventory:adjust\",\n \"orders:read\",\n \"cart:create\",\n \"cart:update\",\n \"mcp:access\",\n ],\n },\n },\n customerPermissions: [\n \"catalog:read\",\n \"cart:create\",\n \"cart:read\",\n \"cart:update\",\n \"orders:create\",\n \"orders:read:own\",\n \"customers:read:self\",\n \"customers:update:self\",\n ],\n },\n entities: {\n product: {\n fields: [\n { name: \"weight\", type: \"number\" },\n { name: \"brand\", type: \"text\" },\n ],\n variants: { enabled: true, optionTypes: [\"size\", \"color\"] },\n fulfillment: \"physical\",\n },\n digitalDownload: {\n fields: [{ name: \"fileAssetId\", type: \"text\" }],\n variants: { enabled: false },\n fulfillment: \"digital-download\",\n },\n course: {\n fields: [{ name: \"modules\", type: \"json\" }],\n variants: { enabled: false },\n fulfillment: \"digital-access\",\n },\n },\n cart: {\n ttlMinutes: 5,\n hooks: {},\n },\n checkout: {\n hooks: {\n beforeCreate: [],\n afterCreate: [],\n },\n },\n orders: {\n hooks: {\n beforeCreate: [],\n afterCreate: [],\n beforeStatusChange: [],\n afterStatusChange: [],\n },\n },\n inventory: {\n hooks: {\n afterAdjust: [],\n },\n },\n email: {\n async send() {\n // no-op for tests\n },\n },\n storage: createInMemoryStorageAdapter(),\n ...overrides,\n });\n}\n\n/**\n * Creates a test config backed by PGlite (in-memory PostgreSQL).\n *\n * This provides production parity for tests by using real SQL execution\n * and PostgreSQL behavior while remaining fast and self-contained.\n *\n * @param overrides - Optional config overrides\n * @returns A promise resolving to an object containing:\n * - config: The CommerceConfig to pass to createKernel\n * - cleanup: Async function to reset data between tests\n */\nexport async function createPGliteTestConfig(\n overrides: Partial<CommerceConfig> = {},\n): Promise<{ config: CommerceConfig; cleanup: () => Promise<void> }> {\n const { createPGliteTestAdapter } = await import(\"./create-pglite-adapter\");\n const { adapter, cleanup } = await createPGliteTestAdapter();\n\n const config = await createTestConfig({\n databaseAdapter: adapter,\n ...overrides,\n });\n\n return { config, cleanup };\n}\n",
|
|
135
|
+
"import type { CommerceConfig } from \"../config/types\";\nimport { createKernel } from \"../runtime/kernel\";\nimport { createTestConfig } from \"./create-test-config\";\n\nexport async function createTestKernel(overrides: Partial<CommerceConfig> = {}) {\n return createKernel(await createTestConfig(overrides));\n}\n",
|
|
136
|
+
"import { HookRegistry } from \"../kernel/hooks/registry\";\nimport { createLogger } from \"../utils/logger\";\nimport { createTestConfig } from \"./create-test-config\";\nimport type { CommerceConfig, MCPTool } from \"../config/types\";\n\ninterface PluginContextShape {\n hooks: HookRegistry;\n config: CommerceConfig;\n services: Record<string, unknown>;\n routes: { add(method: string, path: string, handler: (...args: unknown[]) => unknown): void };\n mcp: { registerTool(tool: MCPTool): void };\n analytics: { registerModel(model: unknown): void };\n database: {\n registerSchema(schema: Record<string, unknown>): void;\n query: unknown;\n transaction<T>(fn: (tx: unknown) => Promise<T>): Promise<T>;\n };\n logger: { info(message: string, data?: unknown): void; warn(message: string, data?: unknown): void; error(message: string, data?: unknown): void };\n}\n\nexport interface TestPluginContext extends PluginContextShape {\n registeredRoutes: Array<{ method: string; path: string; handler: (...args: unknown[]) => unknown }>;\n registeredMCPTools: MCPTool[];\n registeredAnalyticsModels: unknown[];\n registeredSchemas: Array<Record<string, unknown>>;\n}\n\nexport async function createTestPluginContext(options?: {\n config?: Partial<CommerceConfig>;\n services?: Record<string, unknown>;\n}): Promise<TestPluginContext> {\n const hooks = new HookRegistry();\n const config = await createTestConfig(options?.config ?? {});\n const services = options?.services ?? {};\n\n const registeredRoutes: TestPluginContext[\"registeredRoutes\"] = [];\n const registeredMCPTools: MCPTool[] = [];\n const registeredAnalyticsModels: unknown[] = [];\n const registeredSchemas: Array<Record<string, unknown>> = [];\n\n return {\n hooks,\n config,\n services,\n routes: {\n add(method, path, handler) {\n registeredRoutes.push({ method: method.toUpperCase(), path, handler });\n },\n },\n mcp: {\n registerTool(tool) {\n registeredMCPTools.push(tool);\n },\n },\n analytics: {\n registerModel(model) {\n registeredAnalyticsModels.push(model);\n },\n },\n database: {\n registerSchema(schema) {\n registeredSchemas.push(schema);\n },\n query: {},\n async transaction<T>(fn: (tx: unknown) => Promise<T>): Promise<T> {\n return fn({});\n },\n },\n logger: createLogger(\"test-plugin-context\"),\n registeredRoutes,\n registeredMCPTools,\n registeredAnalyticsModels,\n registeredSchemas,\n };\n}\n",
|
|
137
|
+
"import type { CommerceConfig } from \"../config/types\";\nimport { createTestConfig } from \"./create-test-config\";\nimport { createKernel } from \"../runtime/kernel\";\n\nexport interface RepositoryTestHarness {\n config: CommerceConfig;\n kernel: ReturnType<typeof createKernel>;\n}\n\nexport async function createRepositoryTestHarness(\n overrides: Partial<CommerceConfig> = {},\n): Promise<RepositoryTestHarness> {\n const config = await createTestConfig(overrides);\n const kernel = createKernel(config);\n return { config, kernel };\n}\n",
|
|
138
|
+
"/**\n * One-call plugin E2E test setup.\n *\n * Boots a PGlite kernel (or real PG if overridden), programmatically pushes\n * the merged schema (core + plugin tables) via drizzle-kit/api, mounts the\n * test actor middleware on an OpenAPIHono instance, and registers all plugin\n * routes --- matching the production server.ts boot sequence.\n *\n * Usage:\n * import { createPluginTestApp, jsonHeaders, testAdminActor } from \"@unifiedcommerce/core\";\n * const { app } = await createPluginTestApp(myPlugin());\n * const res = await app.request(\"/api/my-route\", {\n * method: \"POST\",\n * headers: jsonHeaders(testAdminActor),\n * body: JSON.stringify({ ... }),\n * });\n * expect(res.status).toBe(201);\n */\n\nimport { OpenAPIHono } from \"@hono/zod-openapi\";\nimport { createRequire } from \"node:module\";\nimport type { PgDatabase, PgQueryResultHKT } from \"drizzle-orm/pg-core\";\nimport type { CommerceConfig, CommercePlugin } from \"../config/types\";\nimport type { Actor } from \"../auth/types\";\nimport { createTestConfig } from \"./create-test-config\";\nimport { createKernel } from \"../runtime/kernel\";\nimport type { Kernel } from \"../runtime/kernel\";\nimport { buildSchema } from \"../kernel/database/migrate\";\nimport { ensureDefaultOrg } from \"../auth/org\";\n\n// drizzle-kit/api uses CJS internally; createRequire provides ESM compat.\nconst require = createRequire(import.meta.url);\n\ntype DrizzleKitPushResult = {\n hasDataLoss: boolean;\n warnings: string[];\n statementsToExecute: string[];\n apply: () => Promise<void>;\n};\n\n/**\n * Hono environment type for the test app. Declares the `actor` context\n * variable so c.set(\"actor\", ...) / c.get(\"actor\") are properly typed\n * without `as never` casts.\n */\nexport type TestAppEnv = {\n Variables: {\n actor: Actor | null;\n };\n};\n\nexport interface PluginTestApp {\n /** OpenAPIHono instance with test actor middleware and all plugin routes registered. */\n app: OpenAPIHono<TestAppEnv>;\n /** The booted kernel with database, services, and config. */\n kernel: Kernel;\n /** Drizzle database instance for direct queries in test assertions. */\n db: PgDatabase<PgQueryResultHKT, Record<string, unknown>>;\n}\n\n/**\n * Creates a fully-wired test application for plugin E2E testing.\n *\n * @param plugin - The plugin under test (e.g., `appointmentPlugin()`)\n * @param configOverrides - Optional config overrides. Pass `databaseAdapter`\n * to use a real PostgreSQL instance instead of PGlite.\n */\nexport async function createPluginTestApp(\n plugin: CommercePlugin,\n configOverrides: Partial<CommerceConfig> = {},\n): Promise<PluginTestApp> {\n // 1. Build config with plugin applied (PGlite auto-provisioned if no adapter)\n const config = await createTestConfig({\n plugins: [plugin],\n ...configOverrides,\n });\n\n // 2. Boot kernel (creates core services, hook registry)\n const kernel = createKernel(config);\n\n // 3. Merge core + plugin schemas\n const mergedSchema = buildSchema(config);\n\n // 4. Programmatic schema push via drizzle-kit/api\n // Diffs current DB state against pgTable definitions, generates DDL, applies it.\n // On fresh PGlite: creates all tables. On existing DB: creates only missing tables.\n const drizzleKit = require(\"drizzle-kit/api\") as {\n pushSchema(\n imports: Record<string, unknown>,\n drizzleInstance: PgDatabase<PgQueryResultHKT>,\n ): Promise<DrizzleKitPushResult>;\n };\n const { apply } = await drizzleKit.pushSchema(\n mergedSchema,\n kernel.database.db as PgDatabase<PgQueryResultHKT>,\n );\n await apply();\n\n // Ensure the default organization exists for plugin tests\n await ensureDefaultOrg(kernel.database.db);\n\n // 5. Create OpenAPIHono --- matching production server.ts\n // Plugin routes register via manifest.ts which calls app.openapi().\n const app = new OpenAPIHono<TestAppEnv>();\n\n // 6. Test actor middleware: parse x-test-actor header -> set on context\n app.use(\"*\", async (c, next) => {\n const header = c.req.header(\"x-test-actor\");\n if (header) {\n try {\n c.set(\"actor\", JSON.parse(header) as Actor);\n } catch { /* malformed JSON --- fall through without actor */ }\n }\n await next();\n });\n\n // 7. Register plugin routes (deferred via config.routes)\n const routes = config.routes as\n | ((app: unknown, kernel: unknown) => void)\n | undefined;\n routes?.(app, kernel);\n\n return {\n app,\n kernel,\n db: kernel.database.db as PgDatabase<PgQueryResultHKT, Record<string, unknown>>,\n };\n}\n",
|
|
139
|
+
"import type { Actor } from \"../auth/types\";\n\n/** Admin with wildcard permissions. Use for setup operations in beforeAll. */\nexport const testAdminActor: Actor = {\n type: \"user\",\n userId: \"test-admin-1\",\n email: \"admin@test.local\",\n name: \"Test Admin\",\n vendorId: null,\n organizationId: \"org_default\",\n role: \"admin\",\n permissions: [\"*:*\"],\n};\n\n/** Staff with common operational permissions. */\nexport const testStaffActor: Actor = {\n type: \"user\",\n userId: \"test-staff-1\",\n email: \"staff@test.local\",\n name: \"Test Staff\",\n vendorId: null,\n organizationId: \"org_default\",\n role: \"staff\",\n permissions: [\n \"catalog:read\", \"catalog:create\", \"catalog:update\",\n \"inventory:adjust\", \"orders:read\", \"orders:create\", \"orders:update\",\n ],\n};\n\n/** Customer with minimal read/write-own permissions. */\nexport const testCustomerActor: Actor = {\n type: \"user\",\n userId: \"test-customer-1\",\n email: \"customer@test.local\",\n name: \"Test Customer\",\n vendorId: null,\n organizationId: \"org_default\",\n role: \"customer\",\n permissions: [\"catalog:read\", \"cart:create\", \"cart:read\", \"orders:read:own\"],\n};\n\n/** Actor with zero permissions. Use for negative auth/perm tests. */\nexport const testNoPermActor: Actor = {\n type: \"user\",\n userId: \"test-noperm-1\",\n email: \"noperm@test.local\",\n name: \"No Permissions\",\n vendorId: null,\n organizationId: \"org_default\",\n role: \"customer\",\n permissions: [],\n};\n\n/**\n * Builds request headers with optional test actor injection.\n * The x-test-actor header is parsed by createPluginTestApp's middleware.\n */\nexport function jsonHeaders(actor?: Actor): Record<string, string> {\n const headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (actor) headers[\"x-test-actor\"] = JSON.stringify(actor);\n return headers;\n}\n",
|
|
140
|
+
"import type { PluginHookRegistration } from \"../kernel/plugin/manifest\";\nimport type { HookContext, HookOperation } from \"../kernel/hooks/types\";\n\n/**\n * Creates a typed before-hook registration for plugins.\n *\n * Narrows the handler signature from the loose `(...args: unknown[]) => unknown`\n * on PluginHookRegistration to the actual `{ data, operation, context }` shape,\n * providing autocomplete on context.jobs.enqueue(), context.logger.info(), etc.\n *\n * @example\n * ```typescript\n * hooks: () => [\n * beforeHook<{ customerId: string }>(\"orders.beforeCreate\", async ({ data, context }) => {\n * context.logger.info(\"order_creating\", { customerId: data.customerId });\n * return data;\n * }),\n * ],\n * ```\n */\nexport function beforeHook<TData>(\n key: string,\n handler: (args: {\n data: TData;\n operation: HookOperation;\n context: HookContext;\n }) => Promise<TData> | TData,\n): PluginHookRegistration {\n return { key, handler: handler as PluginHookRegistration[\"handler\"] };\n}\n\n/**\n * Creates a typed after-hook registration for plugins.\n *\n * @example\n * ```typescript\n * hooks: () => [\n * afterHook<{ id: string; grandTotal: number }>(\"orders.afterCreate\", async ({ result, context }) => {\n * await context.jobs.enqueue(\"loyalty:award-points\", { orderId: result.id });\n * }),\n * ],\n * ```\n */\nexport function afterHook<TData>(\n key: string,\n handler: (args: {\n data: TData | null;\n result: TData;\n operation: HookOperation;\n context: HookContext;\n }) => Promise<void> | void,\n): PluginHookRegistration {\n return { key, handler: handler as PluginHookRegistration[\"handler\"] };\n}\n",
|
|
141
|
+
"export { defineConfig } from \"./config/define-config\";\nexport type {\n CommerceConfig,\n CommercePlugin,\n MCPResource,\n MCPTool,\n} from \"./config/types\";\nexport { defineCommercePlugin } from \"./kernel/plugin/manifest\";\nexport type {\n CommercePluginManifest,\n PluginContext,\n PluginHookRegistration,\n PluginLogger,\n PluginPermission,\n PluginRouteRegistration,\n} from \"./kernel/plugin/manifest\";\n\nexport { router } from \"./interfaces/rest/router\";\nexport { webhookRouter, type WebhookRouterResult } from \"./interfaces/rest/webhook-router\";\nexport { isPrivateUrl, isPrivateIp } from \"./modules/webhooks/ssrf-guard\";\nexport { createServer } from \"./runtime/server\";\nexport { createLogger } from \"./runtime/logger\";\nexport type { Logger as PinoLogger } from \"./runtime/logger\";\nexport { setupGracefulShutdown } from \"./runtime/shutdown\";\nexport { createKernel } from \"./runtime/kernel\";\nexport type { Kernel } from \"./runtime/kernel\";\nexport { createTestKernel } from \"./test-utils/create-test-kernel\";\nexport { createTestPluginContext } from \"./test-utils/create-test-plugin-context\";\nexport { createRepositoryTestHarness } from \"./test-utils/create-repository-test-harness\";\nexport { createPluginTestApp, type PluginTestApp, type TestAppEnv } from \"./test-utils/create-plugin-test-app\";\nexport {\n testAdminActor, testStaffActor, testCustomerActor, testNoPermActor,\n jsonHeaders,\n} from \"./test-utils/test-actors\";\nexport { beforeHook, afterHook } from \"./test-utils/typed-hooks\";\n\nexport type { Actor } from \"./auth/types\";\nexport { resolveOrgId, ensureDefaultOrg, DEFAULT_ORG_ID } from \"./auth/org\";\nexport { OrganizationService } from \"./modules/organization/service\";\nexport { createScopedDb } from \"./kernel/database/scoped-db\";\nexport { assertOwnership, assertPermission } from \"./auth/permissions\";\nexport type { AccessResult, AccessContext, AccessFn, WhereClause } from \"./auth/access\";\nexport {\n accessOR,\n accessAND,\n conditional,\n isAdmin,\n isAuthenticated,\n isDocumentOwner,\n publicAccess,\n denyAll,\n} from \"./auth/access\";\n\nexport { HookRegistry } from \"./kernel/hooks/registry\";\nexport type {\n BeforeHook,\n AfterHook,\n HookContext,\n HookOperation,\n HookOrigin,\n Logger,\n ServiceContainer,\n} from \"./kernel/hooks/types\";\nexport { runBeforeHooks, runAfterHooks } from \"./kernel/hooks/executor\";\nexport { createHookContext } from \"./kernel/hooks/create-context\";\nexport type { CreateHookContextArgs } from \"./kernel/hooks/create-context\";\nexport type { JobsAdapter, EnqueueOptions } from \"./kernel/jobs/adapter\";\nexport { NullJobsAdapter } from \"./kernel/jobs/adapter\";\nexport { DrizzleJobsAdapter } from \"./kernel/jobs/drizzle-adapter\";\nexport { runPendingJobs } from \"./kernel/jobs/runner\";\nexport type { RunPendingJobsArgs } from \"./kernel/jobs/runner\";\nexport type {\n TaskDefinition,\n TaskContext,\n TaskRetryConfig,\n} from \"./kernel/jobs/types\";\n\nexport { createLocalAPI, LocalAPI } from \"./kernel/local-api\";\nexport type { CommerceLocalAPI, LocalAPIOptions } from \"./kernel/local-api\";\nexport { createCommerce } from \"./runtime/commerce\";\nexport type { CommerceInstance } from \"./runtime/commerce\";\n\nexport { createAuditService, createNullAuditService } from \"./modules/audit/service\";\nexport type {\n AuditService,\n AuditEntry,\n RecordArgs,\n ListForEntityArgs,\n} from \"./modules/audit/service\";\n\nexport type { Result, PluginResult, PluginResultErr } from \"./kernel/result\";\nexport { Ok, Err, PluginErr } from \"./kernel/result\";\nexport type { PluginDb, PluginTxFn } from \"./kernel/database/plugin-types\";\nexport type { ServiceRegistry } from \"./kernel/service-registry\";\nexport { toHttpError, type HttpErrorResponse } from \"./kernel/http-error\";\nexport { withTiming } from \"./kernel/service-timing\";\n\nexport {\n CommerceNotFoundError,\n CommerceValidationError,\n CommerceForbiddenError,\n CommerceConflictError,\n CommerceInvalidTransitionError,\n} from \"./kernel/errors\";\n\nexport { mapErrorToStatus } from \"./kernel/error-mapper\";\n\nexport {\n canTransition,\n assertTransition,\n orderStateMachine,\n extendOrderStateMachine,\n} from \"./kernel/state-machine/machine\";\n\nexport type {\n PaymentAdapter,\n PaymentCapture,\n PaymentIntent,\n PaymentRefund,\n PaymentWebhookEvent,\n} from \"./modules/payments/adapter\";\nexport type { StorageAdapter } from \"./modules/media/adapter\";\nexport type {\n SearchAdapter,\n SearchDocument,\n SearchFilters,\n SearchHit,\n SearchQueryParams,\n SearchQueryResult,\n SearchSuggestParams,\n} from \"./modules/search/adapter\";\nexport type { DatabaseAdapter } from \"./kernel/database/adapter\";\nexport {\n createTxContext,\n reuseOrCreateTxContext,\n withTransaction,\n} from \"./kernel/database/tx-context\";\nexport type {\n TxContext,\n WithTransactionOptions,\n} from \"./kernel/database/tx-context\";\nexport type {\n TaxAdapter,\n TaxAddress,\n TaxCalculationParams,\n TaxCalculationResult,\n TaxLineItem,\n TaxReportParams,\n TaxVoidParams,\n} from \"./modules/tax/adapter\";\n\nexport { getSchema, buildSchema, getTableNames } from \"./kernel/database/migrate\";\nexport { consoleEmailAdapter } from \"./adapters/console-email\";\n\nexport { runCompensationChain } from \"./kernel/compensation/executor\";\nexport type {\n CompensationContext,\n Step,\n} from \"./kernel/compensation/types\";\n\nexport { createRepository } from \"./kernel/factory/repository-factory\";\nexport type {\n BaseRepository,\n SoftDeletableRepository,\n RepositoryFor,\n Filters,\n FindOptions,\n} from \"./kernel/factory/repository-factory\";\n\nexport { mergeExtraColumns } from \"./kernel/schema/extra-columns\";\nexport type { ExtraColumnsOption } from \"./kernel/schema/extra-columns\";\n\nexport type { CartItemMatcher } from \"./modules/cart/matcher\";\nexport { defaultCartItemMatcher } from \"./modules/cart/matcher\";\nexport { canAccessCart } from \"./modules/cart/access\";\n\nexport { QueryRegistry } from \"./kernel/query/registry\";\nexport { executeQuery } from \"./kernel/query/executor\";\nexport type {\n RelationDefinition,\n EntityDefinition,\n} from \"./kernel/query/registry\";\nexport type { QueryInput, QueryResult } from \"./kernel/query/executor\";\n\nexport type { CommerceModuleTypes } from \"./types/commerce-types\";\n\nexport { staleOrderCleanupTask } from \"./modules/orders/stale-order-cleanup\";\nexport {\n COMMERCE_AGENT_SYSTEM_PROMPT,\n COMMERCE_AGENT_SYSTEM_PROMPT_COMPACT,\n} from \"./interfaces/mcp/agent-prompt\";\n\nexport { DrizzleAnalyticsAdapter } from \"./modules/analytics/drizzle-adapter\";\nexport { BUILTIN_ANALYTICS_MODELS } from \"./modules/analytics/models\";\nexport { buildAnalyticsScope } from \"./modules/analytics/types\";\nexport type {\n AnalyticsAdapter,\n AnalyticsQueryParams,\n AnalyticsQueryResult,\n AnalyticsMeta,\n AnalyticsModelDefinition,\n AnalyticsScope,\n AnalyticsModel,\n AnalyticsScopeRule,\n AnalyticsMeasure,\n AnalyticsDimension,\n AnalyticsJoin,\n // Deprecated aliases (remove in next major)\n CubeScopeRule,\n CubeDefinition,\n MeasureDefinition,\n DimensionDefinition,\n JoinDefinition,\n} from \"./modules/analytics/types\";\n",
|
|
142
|
+
"import type { Actor } from \"./types\";\n\n/**\n * A WhereClause is a plain object representing database filter conditions.\n * The shape mirrors what services and repositories can accept to narrow queries.\n *\n * Example: { customerId: \"abc-123\" } narrows results to that customer's records.\n * Composite: { or: [{ customerId: \"x\" }, { organizationId: \"y\" }] }\n */\nexport type WhereClause = Record<string, unknown>;\n\n/**\n * AccessResult: the return value of an access function.\n *\n * - `true`: full access, no filter needed\n * - `false`: no access at all\n * - `WhereClause`: partial access — the caller should apply this as a query filter\n */\nexport type AccessResult = boolean | WhereClause;\n\n/**\n * AccessContext carries everything an access function needs to make a decision.\n *\n * - `actor`: the authenticated user/api-key/null (anonymous)\n * - `data`: the document being accessed (for document-level checks)\n * - `id`: the document ID (when data isn't loaded yet)\n */\nexport interface AccessContext<TData = unknown> {\n actor: Actor | null;\n data?: TData;\n id?: string;\n req?: Request;\n}\n\n/**\n * An AccessFn evaluates access for a given context.\n * Returns boolean (full/no access) or WhereClause (filtered access).\n */\nexport type AccessFn<TData = unknown> = (\n ctx: AccessContext<TData>,\n) => AccessResult | Promise<AccessResult>;\n\n/**\n * Combines multiple WhereClause objects with a logical operator.\n * If there's only one clause, returns it directly (no unnecessary nesting).\n */\nfunction combineWhere(\n queries: WhereClause[],\n operator: \"and\" | \"or\",\n): WhereClause {\n if (queries.length === 1) return queries[0]!;\n return { [operator]: queries };\n}\n\n/**\n * Composes access functions with OR semantics.\n *\n * - If ANY function returns `true`, grants full access immediately (short-circuit).\n * - If one or more return WhereClause, combines them with OR.\n * - If ALL return `false`, denies access.\n *\n * Example:\n * ```typescript\n * const orderReadAccess = accessOR(isAdmin, isDocumentOwner(\"customerId\"))\n * // Admins see all orders; customers see only their own\n * ```\n */\nexport const accessOR = <TData = unknown>(\n ...fns: Array<AccessFn<TData>>\n): AccessFn<TData> => {\n return async (ctx) => {\n const queries: WhereClause[] = [];\n for (const fn of fns) {\n const result = await fn(ctx);\n if (result === true) return true;\n if (result && typeof result === \"object\") queries.push(result);\n }\n if (queries.length > 0) return combineWhere(queries, \"or\");\n return false;\n };\n};\n\n/**\n * Composes access functions with AND semantics.\n *\n * - If ANY function returns `false`, denies access immediately (short-circuit).\n * - If one or more return WhereClause, combines them with AND.\n * - If ALL return `true`, grants full access.\n *\n * Example:\n * ```typescript\n * const restrictedAccess = accessAND(isAuthenticated, isDocumentOwner(\"customerId\"))\n * // Must be logged in AND own the document\n * ```\n */\nexport const accessAND = <TData = unknown>(\n ...fns: Array<AccessFn<TData>>\n): AccessFn<TData> => {\n return async (ctx) => {\n const queries: WhereClause[] = [];\n for (const fn of fns) {\n const result = await fn(ctx);\n if (result === false) return false;\n if (result !== true && result && typeof result === \"object\") {\n queries.push(result);\n }\n }\n if (queries.length > 0) return combineWhere(queries, \"and\");\n return true;\n };\n};\n\n/**\n * Switches between two access functions based on a condition.\n *\n * Example:\n * ```typescript\n * const accessByRole = conditional(\n * ({ actor }) => actor?.role === \"vendor\",\n * isDocumentOwner(\"vendorId\"),\n * isAdmin,\n * )\n * ```\n */\nexport const conditional = <TData = unknown>(\n condition: ((ctx: AccessContext<TData>) => boolean) | boolean,\n accessFn: AccessFn<TData>,\n fallback: AccessFn<TData> = () => false,\n): AccessFn<TData> => {\n return async (ctx) => {\n const applies =\n typeof condition === \"function\" ? condition(ctx) : condition;\n return applies ? accessFn(ctx) : fallback(ctx);\n };\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Built-in access functions\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Grants access if the actor has admin or owner role (wildcard permissions).\n */\nexport const isAdmin: AccessFn = ({ actor }) => {\n if (!actor) return false;\n return actor.permissions.includes(\"*:*\");\n};\n\n/**\n * Grants access if the actor is authenticated (any role).\n */\nexport const isAuthenticated: AccessFn = ({ actor }) => {\n return actor != null;\n};\n\n/**\n * Returns a WhereClause that filters to documents owned by the actor.\n * The ownerField is the column name that holds the owner's user ID.\n *\n * For document-level checks (when data is provided), returns true/false.\n * For list-level checks (when data is not provided), returns a WhereClause.\n */\nexport const isDocumentOwner = (\n ownerField = \"customerId\",\n): AccessFn => {\n return ({ actor, data }) => {\n if (!actor) return false;\n\n // Document-level check: compare directly\n if (data) {\n return (data as Record<string, unknown>)[ownerField] === actor.userId;\n }\n\n // List-level check: return a filter clause\n return { [ownerField]: actor.userId };\n };\n};\n\n/**\n * Grants access to everyone, including anonymous users.\n */\nexport const publicAccess: AccessFn = () => true;\n\n/**\n * Denies access to everyone.\n */\nexport const denyAll: AccessFn = () => false;\n",
|
|
143
|
+
"/**\n * Converts a PluginResultErr into a structured HTTP error response.\n *\n * Replaces the `throw new Error(result.error)` pattern in plugin routes\n * which always produces HTTP 500 with no structured error code.\n *\n * Usage in routes:\n * const result = await service.doSomething(orgId, input);\n * if (!result.ok) return toHttpError(result);\n * return result.value;\n *\n * The function infers HTTP status from the error code or message content:\n * - \"NOT_FOUND\" or \"not found\" --> 404\n * - \"FORBIDDEN\" or \"permission\" --> 403\n * - \"CONFLICT\" or \"already exists\" --> 409\n * - \"VALIDATION\" or \"cannot/must\" --> 422\n * - Everything else --> 400\n */\n\nimport type { PluginResultErr } from \"./result\";\n\nexport interface HttpErrorResponse {\n status: 400 | 403 | 404 | 409 | 422;\n body: { error: { code: string; message: string } };\n}\n\nexport function toHttpError(result: PluginResultErr): HttpErrorResponse {\n const message = result.error;\n const code = result.code;\n\n if (code === \"NOT_FOUND\" || /not found/i.test(message)) {\n return { status: 404, body: { error: { code: \"NOT_FOUND\", message } } };\n }\n if (code === \"FORBIDDEN\" || /permission|forbidden|unauthorized/i.test(message)) {\n return { status: 403, body: { error: { code: \"FORBIDDEN\", message } } };\n }\n if (code === \"CONFLICT\" || /already|duplicate|exists|unique/i.test(message)) {\n return { status: 409, body: { error: { code: \"CONFLICT\", message } } };\n }\n if (code === \"VALIDATION\" || /invalid|cannot|must|required|exceeded|negative/i.test(message)) {\n return { status: 422, body: { error: { code: \"VALIDATION_FAILED\", message } } };\n }\n return { status: 400, body: { error: { code: code ?? \"BAD_REQUEST\", message } } };\n}\n",
|
|
144
|
+
"/**\n * Development email adapter that logs emails to the console.\n *\n * Zero dependencies. Use this during local development to see email\n * content in the terminal without configuring Resend or an SMTP server.\n *\n * @example\n * ```typescript\n * import { consoleEmailAdapter } from \"@unifiedcommerce/core\";\n *\n * export default defineConfig({\n * email: consoleEmailAdapter(),\n * });\n * ```\n */\nexport function consoleEmailAdapter(): {\n send(input: { template: string; to: string; data?: Record<string, unknown> }): Promise<void>;\n} {\n return {\n async send(input) {\n const divider = \"=\".repeat(60);\n const lines = [\n \"\",\n divider,\n ` EMAIL: ${input.template}`,\n divider,\n ` To: ${input.to}`,\n ` Template: ${input.template}`,\n ];\n\n if (input.data && Object.keys(input.data).length > 0) {\n lines.push(` Data:`);\n for (const [key, value] of Object.entries(input.data)) {\n lines.push(` ${key}: ${JSON.stringify(value)}`);\n }\n }\n\n lines.push(divider, \"\");\n\n console.log(lines.join(\"\\n\"));\n },\n };\n}\n",
|
|
145
|
+
"import {\n eq,\n and,\n isNull,\n sql,\n getTableColumns,\n type SQL,\n type Column,\n type InferSelectModel,\n type InferInsertModel,\n} from \"drizzle-orm\";\nimport type { PgTableWithColumns, TableConfig } from \"drizzle-orm/pg-core\";\nimport { PgTable } from \"drizzle-orm/pg-core\";\nimport type { TxContext } from \"../database/tx-context\";\nimport type { DrizzleDatabase, DbOrTx } from \"../database/drizzle-db\";\nimport { CommerceNotFoundError } from \"../errors\";\n\n/**\n * Filter type — partial record of column values to match with eq().\n * Only keys that exist on TRow and have non-undefined values are used.\n */\nexport type Filters<TRow> = Partial<TRow>;\n\n/**\n * Options for findMany / findAndCount queries.\n */\nexport interface FindOptions {\n limit?: number;\n offset?: number;\n orderBy?: Array<{ column: string; direction: \"asc\" | \"desc\" }>;\n withDeleted?: boolean;\n}\n\n/**\n * Standard CRUD operations derived from a Drizzle pgTable schema.\n * All methods support optional TxContext for transaction participation.\n */\nexport interface BaseRepository<TRow, TInsert> {\n findById(id: string, ctx?: TxContext): Promise<TRow | undefined>;\n findMany(\n filters?: Filters<TRow>,\n options?: FindOptions,\n ctx?: TxContext,\n ): Promise<TRow[]>;\n findAndCount(\n filters?: Filters<TRow>,\n options?: FindOptions,\n ctx?: TxContext,\n ): Promise<{ rows: TRow[]; total: number }>;\n create(data: TInsert, ctx?: TxContext): Promise<TRow>;\n createMany(data: TInsert[], ctx?: TxContext): Promise<TRow[]>;\n update(id: string, data: Partial<TInsert>, ctx?: TxContext): Promise<TRow>;\n delete(id: string, ctx?: TxContext): Promise<void>;\n}\n\n/**\n * Extended repository for tables with a `deleted_at` column.\n * Adds softDelete and restore operations.\n */\nexport interface SoftDeletableRepository<TRow, TInsert>\n extends BaseRepository<TRow, TInsert> {\n softDelete(id: string, ctx?: TxContext): Promise<void>;\n restore(id: string, ctx?: TxContext): Promise<TRow>;\n}\n\n/**\n * Type-level check: does the table config have a `deletedAt` or `deleted_at` column?\n */\ntype HasDeletedAt<T extends PgTableWithColumns<TableConfig>> =\n \"deletedAt\" extends keyof T ? true : \"deleted_at\" extends keyof T ? true : false;\n\n/**\n * Conditional repository type: if the table has a deleted_at column,\n * return SoftDeletableRepository; otherwise BaseRepository.\n */\nexport type RepositoryFor<T extends PgTableWithColumns<TableConfig>> =\n HasDeletedAt<T> extends true\n ? SoftDeletableRepository<InferSelectModel<T>, InferInsertModel<T>>\n : BaseRepository<InferSelectModel<T>, InferInsertModel<T>>;\n\n/**\n * Creates a typed repository with standard CRUD operations from a Drizzle table schema.\n *\n * Usage:\n * ```typescript\n * const repo = createRepository(schema.promotions, db)\n * const row = await repo.findById(\"abc-123\")\n * const rows = await repo.findMany({ status: \"active\" }, { limit: 10 })\n * ```\n *\n * Tables with a `deletedAt` column automatically get `softDelete()` and `restore()`.\n * Domain-specific queries should remain in dedicated repository classes that\n * delegate standard CRUD to the factory-created instance.\n */\nexport function createRepository<T extends PgTableWithColumns<TableConfig>>(\n table: T,\n db: DrizzleDatabase,\n): RepositoryFor<T> {\n // Use getTableColumns for type-safe column access\n const columns = getTableColumns(table) as Record<string, Column>;\n\n // Runtime check for soft-delete column\n const hasSoftDelete = \"deletedAt\" in columns || \"deleted_at\" in columns;\n const deletedAtColumn: Column | null =\n columns[\"deletedAt\"] ?? columns[\"deleted_at\"] ?? null;\n const idColumn = columns[\"id\"]!;\n\n // Drizzle's generic types require PgTable at the boundary.\n // We cast once here rather than at every call site.\n const pgTable = table as PgTable;\n\n function getDb(ctx?: TxContext): DbOrTx {\n return (ctx?.tx as DbOrTx | undefined) ?? db;\n }\n\n function buildWhereConditions(\n filters?: Filters<InferSelectModel<T>>,\n includeDeleted = false,\n ): SQL[] {\n const conditions: SQL[] = [];\n\n // Automatically exclude soft-deleted rows unless explicitly requested\n if (hasSoftDelete && !includeDeleted && deletedAtColumn) {\n conditions.push(isNull(deletedAtColumn));\n }\n\n if (filters) {\n for (const [key, value] of Object.entries(filters)) {\n const col = columns[key];\n if (value !== undefined && col) {\n conditions.push(eq(col, value));\n }\n }\n }\n\n return conditions;\n }\n\n const repo: BaseRepository<InferSelectModel<T>, InferInsertModel<T>> = {\n async findById(id, ctx) {\n const conditions = buildWhereConditions(undefined, false);\n conditions.push(eq(idColumn, id));\n const rows = await getDb(ctx)\n .select()\n .from(pgTable)\n .where(and(...conditions));\n return rows[0] as InferSelectModel<T> | undefined;\n },\n\n async findMany(filters, options = {}, ctx) {\n const conditions = buildWhereConditions(filters, options.withDeleted);\n let query = getDb(ctx).select().from(pgTable).$dynamic();\n if (conditions.length > 0) {\n query = query.where(and(...conditions));\n }\n if (options.limit !== undefined) {\n query = query.limit(options.limit);\n }\n if (options.offset !== undefined) {\n query = query.offset(options.offset);\n }\n return query as unknown as Promise<InferSelectModel<T>[]>;\n },\n\n async findAndCount(filters, options = {}, ctx) {\n const rows = await repo.findMany(filters, options, ctx);\n const conditions = buildWhereConditions(filters, options.withDeleted);\n let countQuery = getDb(ctx)\n .select({ count: sql<number>`count(*)::int` })\n .from(pgTable)\n .$dynamic();\n if (conditions.length > 0) {\n countQuery = countQuery.where(and(...conditions));\n }\n const countResult = await countQuery;\n return { rows, total: countResult[0]?.count ?? 0 };\n },\n\n async create(data, ctx) {\n const rows = await getDb(ctx)\n .insert(pgTable)\n .values(data as Record<string, unknown>)\n .returning();\n return rows[0] as InferSelectModel<T>;\n },\n\n async createMany(data, ctx) {\n if (data.length === 0) return [];\n const rows = await getDb(ctx)\n .insert(pgTable)\n .values(data as Record<string, unknown>[])\n .returning();\n return rows as InferSelectModel<T>[];\n },\n\n async update(id, data, ctx) {\n const rows = await getDb(ctx)\n .update(pgTable)\n .set(data as Record<string, unknown>)\n .where(eq(idColumn, id))\n .returning();\n if (!rows[0]) {\n throw new CommerceNotFoundError(`Record ${id} not found.`);\n }\n return rows[0] as InferSelectModel<T>;\n },\n\n async delete(id, ctx) {\n await getDb(ctx).delete(pgTable).where(eq(idColumn, id));\n },\n };\n\n if (hasSoftDelete && deletedAtColumn) {\n const softRepo = repo as SoftDeletableRepository<\n InferSelectModel<T>,\n InferInsertModel<T>\n >;\n\n softRepo.softDelete = async (id, ctx) => {\n await getDb(ctx)\n .update(pgTable)\n .set({ deletedAt: new Date() } as Record<string, unknown>)\n .where(eq(idColumn, id));\n };\n\n softRepo.restore = async (id, ctx) => {\n const rows = await getDb(ctx)\n .update(pgTable)\n .set({ deletedAt: null } as Record<string, unknown>)\n .where(eq(idColumn, id))\n .returning();\n if (!rows[0]) {\n throw new CommerceNotFoundError(`Record ${id} not found.`);\n }\n return rows[0] as InferSelectModel<T>;\n };\n\n return softRepo as RepositoryFor<T>;\n }\n\n return repo as RepositoryFor<T>;\n}\n",
|
|
146
|
+
"import type { PgColumnBuilderBase } from \"drizzle-orm/pg-core\";\n\n/**\n * Options for modules that support schema extension via extra columns.\n *\n * Usage:\n * ```typescript\n * const catalogModule = createCatalogModule({\n * extraColumns: (base) => ({\n * supplierCode: text(\"supplier_code\"),\n * gtin: text(\"gtin\").unique(),\n * }),\n * });\n * ```\n */\nexport interface ExtraColumnsOption<TBaseColumns extends Record<string, unknown>> {\n extraColumns?: (\n baseColumns: TBaseColumns,\n ) => Record<string, PgColumnBuilderBase>;\n}\n\n/**\n * Merges base columns with optional extra columns from configuration.\n * Returns the combined column definitions for use in `pgTable()`.\n */\nexport function mergeExtraColumns<\n TBase extends Record<string, unknown>,\n>(\n baseColumns: TBase,\n extraColumnsFn?: (base: TBase) => Record<string, PgColumnBuilderBase>,\n): TBase & Record<string, PgColumnBuilderBase> {\n if (!extraColumnsFn) return baseColumns as TBase & Record<string, PgColumnBuilderBase>;\n const extra = extraColumnsFn(baseColumns);\n return { ...baseColumns, ...extra };\n}\n\n\n",
|
|
147
|
+
"import type { Actor } from \"../../auth/types\";\nimport type { Cart } from \"./repository\";\n\n/**\n * Determines whether an actor can access a cart.\n *\n * Access is granted if:\n * 1. The actor is authenticated and owns the cart (customerId match)\n * 2. The provided secret matches the cart's secret (guest access)\n */\nexport function canAccessCart(\n actor: Actor | null,\n cart: Cart,\n providedSecret?: string,\n): boolean {\n // Authenticated owner\n if (actor && cart.customerId && actor.userId === cart.customerId) {\n return true;\n }\n\n // Valid secret (guest access)\n if (providedSecret && cart.secret && providedSecret === cart.secret) {\n return true;\n }\n\n return false;\n}\n",
|
|
148
|
+
"/**\n * Defines a relation from a parent entity to a related entity.\n * Used by the query executor to batch-load related records.\n */\nexport interface RelationDefinition {\n foreignKey: string;\n targetService: string;\n batchMethod: string;\n attachAs: string;\n isList?: boolean;\n}\n\n/**\n * Defines an entity that can be queried via kernel.query().\n */\nexport interface EntityDefinition {\n service: string;\n getByIdMethod: string;\n listMethod: string;\n relations: Record<string, RelationDefinition>;\n}\n\n/**\n * Registry of queryable entities and their relations.\n * Modules register their entities at kernel boot.\n * Plugins can register additional entities.\n */\nexport class QueryRegistry {\n private entities = new Map<string, EntityDefinition>();\n\n register(name: string, definition: EntityDefinition): void {\n this.entities.set(name, definition);\n }\n\n get(name: string): EntityDefinition | undefined {\n return this.entities.get(name);\n }\n\n has(name: string): boolean {\n return this.entities.has(name);\n }\n\n listEntities(): string[] {\n return [...this.entities.keys()];\n }\n}\n",
|
|
149
|
+
"import { CommerceNotFoundError } from \"../errors\";\nimport type {\n QueryRegistry,\n EntityDefinition,\n RelationDefinition,\n} from \"./registry\";\n\nexport interface QueryInput {\n entity: string;\n id?: string;\n filters?: Record<string, unknown>;\n include?: string[];\n pagination?: { limit?: number; offset?: number };\n}\n\nexport interface QueryResult<T = Record<string, unknown>> {\n data: T[];\n total?: number | undefined;\n}\n\n/**\n * Executes a query against the registry, resolving includes via\n * batched dataloader-style fetches (one WHERE IN per relation).\n */\nexport async function executeQuery<T = Record<string, unknown>>(\n registry: QueryRegistry,\n services: Record<string, unknown>,\n input: QueryInput,\n): Promise<QueryResult<T>> {\n const definition = registry.get(input.entity);\n if (!definition) {\n throw new CommerceNotFoundError(\n `No entity registered with name \"${input.entity}\".`,\n );\n }\n\n const service = services[definition.service] as Record<\n string,\n (...args: unknown[]) => Promise<unknown>\n >;\n\n // 1. Fetch primary records\n let rows: Record<string, unknown>[];\n let total: number | undefined;\n\n if (input.id) {\n const result = (await service[definition.getByIdMethod]!(\n input.id,\n )) as { ok?: boolean; value?: unknown };\n const value = result?.value ?? result;\n rows = value != null ? [value as Record<string, unknown>] : [];\n } else {\n const result = (await service[definition.listMethod]!(\n input.filters ?? {},\n input.pagination,\n )) as {\n ok?: boolean;\n value?: { items?: unknown[]; total?: number };\n };\n const resolved = result?.value ?? result;\n if (resolved && typeof resolved === \"object\" && \"items\" in resolved) {\n rows = (resolved.items ?? []) as Record<string, unknown>[];\n total = resolved.total;\n } else if (Array.isArray(resolved)) {\n rows = resolved as Record<string, unknown>[];\n } else {\n rows = [];\n }\n }\n\n // 2. Resolve includes\n if (input.include?.length) {\n await resolveIncludes(rows, input.include, definition, services, registry);\n }\n\n return { data: rows as T[], total };\n}\n\nasync function resolveIncludes(\n rows: Record<string, unknown>[],\n includes: string[],\n definition: EntityDefinition,\n services: Record<string, unknown>,\n registry: QueryRegistry,\n): Promise<void> {\n // Group includes by top-level segment\n const topLevel = new Map<string, string[]>();\n for (const path of includes) {\n const dot = path.indexOf(\".\");\n if (dot === -1) {\n if (!topLevel.has(path)) topLevel.set(path, []);\n } else {\n const parent = path.substring(0, dot);\n const child = path.substring(dot + 1);\n const existing = topLevel.get(parent) ?? [];\n existing.push(child);\n topLevel.set(parent, existing);\n }\n }\n\n for (const [relationName, nestedIncludes] of topLevel) {\n const relation = definition.relations[relationName];\n if (!relation) continue;\n\n const targetService = services[relation.targetService] as\n | Record<string, (...args: unknown[]) => Promise<unknown>>\n | undefined;\n if (!targetService) continue;\n\n // Collect foreign key values (deduplicated)\n const ids = [\n ...new Set(\n rows\n .map((r) => r[relation.foreignKey])\n .filter((v): v is string => v != null && typeof v === \"string\"),\n ),\n ];\n if (ids.length === 0) continue;\n\n // One batched query\n const batchFn = targetService[relation.batchMethod];\n if (!batchFn) continue;\n\n const relatedResult = await batchFn(ids);\n const relatedRows = extractRows(relatedResult);\n\n // Build lookup\n const map = new Map<string, unknown>();\n for (const related of relatedRows) {\n const rec = related as Record<string, unknown>;\n if (relation.isList) {\n const key = rec[relation.foreignKey] as string;\n if (!map.has(key)) map.set(key, []);\n (map.get(key) as unknown[]).push(rec);\n } else {\n map.set(rec[\"id\"] as string, rec);\n }\n }\n\n // Attach to parent rows\n for (const row of rows) {\n const fkValue = row[relation.foreignKey] as string | undefined;\n if (!fkValue) continue;\n row[relation.attachAs] =\n map.get(fkValue) ?? (relation.isList ? [] : null);\n }\n\n // Resolve nested includes\n if (nestedIncludes.length > 0) {\n const targetDef = registry.get(relation.targetService);\n if (targetDef) {\n const nestedRows = relation.isList\n ? rows.flatMap(\n (r) =>\n (r[relation.attachAs] as Record<string, unknown>[]) ?? [],\n )\n : rows\n .map((r) => r[relation.attachAs] as Record<string, unknown>)\n .filter(Boolean);\n await resolveIncludes(\n nestedRows,\n nestedIncludes,\n targetDef,\n services,\n registry,\n );\n }\n }\n }\n}\n\nfunction extractRows(result: unknown): unknown[] {\n if (Array.isArray(result)) return result;\n if (result && typeof result === \"object\") {\n const r = result as { ok?: boolean; value?: unknown };\n if (r.value != null) {\n if (Array.isArray(r.value)) return r.value;\n if (typeof r.value === \"object\" && \"items\" in r.value) {\n return (r.value as { items: unknown[] }).items;\n }\n }\n }\n return [];\n}\n",
|
|
150
|
+
"import { eq, and, lt, sql } from \"drizzle-orm\";\nimport { orders } from \"./schema\";\nimport type { TaskDefinition, TaskContext } from \"../../kernel/jobs/types\";\n\n/**\n * Stale Order Cleanup Task\n *\n * Cancels orders stuck in \"pending\" status for longer than the configured\n * threshold (default: 48 hours). This releases reserved inventory and\n * refunds captured payments, preventing phantom stock loss from abandoned\n * orders.\n *\n * Register via config.jobs.tasks:\n * ```ts\n * import { staleOrderCleanupTask } from \"@unifiedcommerce/core\";\n * defineConfig({\n * jobs: {\n * tasks: [staleOrderCleanupTask],\n * autorun: { enabled: true, intervalMs: 3600_000 }, // hourly\n * },\n * });\n * ```\n */\nexport const staleOrderCleanupTask: TaskDefinition<\n { thresholdHours?: number },\n { cancelledCount: number; orderIds: string[] }\n> = {\n slug: \"orders/stale-cleanup\",\n\n async handler({ input, ctx }) {\n const thresholdHours = input.thresholdHours ?? 48;\n const cutoff = new Date(Date.now() - thresholdHours * 60 * 60 * 1000);\n\n // Find stale pending orders\n const staleOrders = await ctx.db\n .select()\n .from(orders)\n .where(\n and(\n eq(orders.status, \"pending\"),\n lt(orders.placedAt, cutoff),\n ),\n );\n\n const cancelledIds: string[] = [];\n\n // Cancel each stale order via the service (triggers inventory release + payment refund)\n const orderService = ctx.services.orders as {\n cancel(orderId: string, actor: null, reason: string): Promise<unknown>;\n };\n\n for (const order of staleOrders) {\n try {\n await orderService.cancel(\n order.id,\n null,\n `Auto-cancelled: pending for >${thresholdHours}h`,\n );\n cancelledIds.push(order.id);\n ctx.logger.info(`Stale order ${order.orderNumber} auto-cancelled`, {\n orderId: order.id,\n placedAt: order.placedAt,\n });\n } catch (error) {\n ctx.logger.error(`Failed to cancel stale order ${order.orderNumber}`, { error });\n }\n }\n\n return {\n output: {\n cancelledCount: cancelledIds.length,\n orderIds: cancelledIds,\n },\n };\n },\n};\n",
|
|
151
|
+
"/**\n * System prompt for AI agents interacting with the UnifiedCommerce Engine via MCP.\n *\n * This prompt grounds the agent in the engine's semantic layer, preventing\n * hallucination on metric definitions and guiding correct tool usage.\n *\n * Usage:\n * import { COMMERCE_AGENT_SYSTEM_PROMPT } from \"@unifiedcommerce/core\";\n * // Pass as the system prompt when creating a Claude conversation\n */\n\nexport const COMMERCE_AGENT_SYSTEM_PROMPT = `You are an AI commerce assistant with access to a live e-commerce store via the UnifiedCommerce Engine. You can browse the catalog, manage inventory, create orders, query analytics, and manage marketplace operations.\n\n## CRITICAL: Analytics Grounding Rules\n\nYou have access to a semantic analytics layer with predefined metrics. NEVER guess metric definitions or write raw calculations. Instead:\n\n1. ALWAYS call \\`analytics_meta\\` first to discover what metrics are available before answering any analytics question.\n2. ONLY use measures and dimensions returned by \\`analytics_meta\\`. If a user asks about a metric that doesn't exist (e.g., \"customer acquisition cost\"), say: \"That metric isn't currently tracked. Here are the metrics I can report on: [list available measures].\"\n3. NEVER return 0 as an answer without verifying it's actually zero — if analytics_query returns an error, tell the user the metric isn't available.\n4. When reporting monetary values, all amounts are in the smallest currency unit (cents). Divide by 100 for display: 242626602 cents = $2,426,266.02.\n\n## Available Analytics Measures\n\n### Orders\n- \\`Orders.count\\` — Total number of orders\n- \\`Orders.revenue\\` — Total revenue (SUM of grand_total, in cents)\n- \\`Orders.averageOrderValue\\` — Average order value (in cents)\n- \\`Orders.subtotalRevenue\\` — Revenue before tax/shipping/discounts\n- \\`Orders.taxCollected\\` — Total tax collected\n- \\`Orders.shippingRevenue\\` — Total shipping charges\n- \\`Orders.discountsGiven\\` — Total discounts applied\n- \\`Orders.uniqueCustomers\\` — Distinct customers who placed orders\n\n### Order Line Items\n- \\`OrderLineItems.count\\` — Total line items across all orders\n- \\`OrderLineItems.itemsSold\\` — Total units sold (SUM of quantity)\n- \\`OrderLineItems.lineItemRevenue\\` — Revenue by product\n- \\`OrderLineItems.averageUnitPrice\\` — Average price per unit\n\n### Inventory\n- \\`Inventory.totalOnHand\\` — Total units in warehouses\n- \\`Inventory.totalReserved\\` — Units reserved for pending orders\n- \\`Inventory.totalAvailable\\` — Units available for sale (on_hand - reserved)\n- \\`Inventory.inventoryValue\\` — Total value of inventory (qty × unit cost)\n- \\`Inventory.lowStockCount\\` — Items below reorder threshold\n\n### Customers\n- \\`Customers.customerCount\\` — Total registered customers\n- \\`Customers.newCustomers\\` — New customer count\n- \\`Customers.returningCustomers\\` — Customers with more than one order\n\n## Available Dimensions (for GROUP BY)\n\n- \\`Orders.status\\` — pending, confirmed, processing, fulfilled, cancelled, refunded\n- \\`Orders.placedAt\\` — Time dimension (supports day/week/month/year granularity)\n- \\`Orders.currency\\` — Currency code\n- \\`OrderLineItems.title\\` — Product name (use for \"top products\" queries)\n- \\`OrderLineItems.entityType\\` — Product type\n- \\`Inventory.warehouseId\\` — Warehouse UUID\n- \\`Inventory.entityId\\` — Product UUID\n- \\`Customers.createdAt\\` — Customer registration date\n\n## Query Examples\n\n**\"What was our revenue last month?\"**\n\\`\\`\\`json\n{\n \"measures\": [\"Orders.revenue\", \"Orders.count\"],\n \"timeDimensions\": [{\n \"dimension\": \"Orders.placedAt\",\n \"granularity\": \"month\",\n \"dateRange\": \"last month\"\n }]\n}\n\\`\\`\\`\n\n**\"Top 5 products by units sold\"**\n\\`\\`\\`json\n{\n \"measures\": [\"OrderLineItems.itemsSold\"],\n \"dimensions\": [\"OrderLineItems.title\"],\n \"order\": { \"OrderLineItems.itemsSold\": \"desc\" },\n \"limit\": 5\n}\n\\`\\`\\`\n\n**\"Revenue by status\"**\n\\`\\`\\`json\n{\n \"measures\": [\"Orders.revenue\", \"Orders.count\"],\n \"dimensions\": [\"Orders.status\"]\n}\n\\`\\`\\`\n\n**\"Monthly revenue trend for 2025\"**\n\\`\\`\\`json\n{\n \"measures\": [\"Orders.revenue\"],\n \"timeDimensions\": [{\n \"dimension\": \"Orders.placedAt\",\n \"granularity\": \"month\",\n \"dateRange\": [\"2025-01-01\", \"2025-12-31\"]\n }]\n}\n\\`\\`\\`\n\n## Available Tools\n\n### Catalog\n- \\`catalog_search\\` — Search products with filters (type, query, category, brand)\n- \\`catalog_create_entity\\` — Create a new product\n\n### Inventory\n- \\`inventory_check\\` — Check available stock for product(s)\n- \\`inventory_adjust\\` — Add or remove stock\n\n### Cart & Orders\n- \\`cart_create\\` — Create a shopping cart\n- \\`cart_add_item\\` — Add item to cart\n- \\`order_get\\` — Get order details by ID\n- \\`order_list\\` — List orders with pagination\n\n### Analytics\n- \\`analytics_query\\` — Query analytics with measures, dimensions, filters, time dimensions\n- \\`analytics_meta\\` — List all available measures, dimensions, and models\n\n### Marketplace (if marketplace plugin is enabled)\n- \\`marketplace_vendor_list\\` — List marketplace vendors\n- \\`marketplace_vendor_performance\\` — Get vendor metrics and rating\n- \\`marketplace_vendor_balance\\` — Get vendor balance and ledger\n- \\`marketplace_suborder_update\\` — Transition sub-order status\n- \\`marketplace_dispute_summary\\` — List open disputes\n- \\`marketplace_payout_run\\` — Trigger vendor payout cycle\n- \\`marketplace_commission_preview\\` — Preview commission rate\n- \\`marketplace_rfq_list\\` — List open RFQs (B2B)\n\n## Available Resources\n\n- \\`commerce://schema/entity-types\\` — Product type definitions with fields and variants\n- \\`commerce://schema/order-states\\` — Order state machine with valid transitions\n\n## Order State Machine\n\nOrders follow this lifecycle:\n\\`\\`\\`\npending → confirmed → processing → [partially_fulfilled | fulfilled] → refunded\n ↘ cancelled (from any non-terminal state)\n\\`\\`\\`\n\nWhen answering questions about order statuses, use the state machine to determine valid transitions. Don't suggest transitions that aren't allowed.\n\n## Response Guidelines\n\n1. **Be specific with numbers.** Don't say \"revenue increased\" — say \"revenue was $42,001.03 in November, up 43% from October's $29,799.44.\"\n2. **Always include units.** Monetary values in dollars (divide cents by 100), quantities as \"units\", time periods explicitly.\n3. **Cite the source.** When reporting analytics, mention which measure you queried: \"Based on Orders.revenue grouped by month...\"\n4. **Suggest follow-ups.** After answering, suggest related queries: \"Would you like to see this broken down by product? Or compare with the previous quarter?\"\n5. **Handle errors gracefully.** If a tool call fails, explain what went wrong and suggest alternatives.\n`;\n\n/**\n * Shorter version for token-constrained contexts.\n */\nexport const COMMERCE_AGENT_SYSTEM_PROMPT_COMPACT = `You are an AI commerce assistant with MCP access to a live store.\n\nCRITICAL: For analytics, ALWAYS call analytics_meta first to discover available metrics. Only use measures/dimensions listed there. All monetary values are in cents — divide by 100 for display.\n\nKey measures: Orders.revenue, Orders.count, Orders.averageOrderValue, OrderLineItems.itemsSold, Inventory.totalAvailable, Customers.customerCount.\nKey dimensions: Orders.status, Orders.placedAt (time), OrderLineItems.title (products).\nTime ranges: \"last month\", \"this month\", \"Q1 2026\", or [\"2025-01-01\", \"2025-12-31\"].\n\nIf a metric doesn't exist, say so and list what IS available. Never guess or return 0 without verification.\n`;\n"
|
|
152
|
+
],
|
|
153
|
+
"mappings": "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",
|
|
154
|
+
"debugId": "E0B9860AE3B8179864756E2164756E21",
|
|
155
|
+
"names": []
|
|
156
|
+
}
|