diff --git a/apps/api/karrio/server/settings/base.py b/apps/api/karrio/server/settings/base.py index 50ec5cff9..b6db54b30 100644 --- a/apps/api/karrio/server/settings/base.py +++ b/apps/api/karrio/server/settings/base.py @@ -195,12 +195,8 @@ ("APPS_MANAGEMENT", bool), ("DOCUMENTS_MANAGEMENT", bool), ("DATA_IMPORT_EXPORT", bool), - ("CUSTOM_CARRIER_DEFINITION", bool), ("PERSIST_SDK_TRACING", bool), - ("ORDER_DATA_RETENTION", int), - ("TRACKER_DATA_RETENTION", int), - ("SHIPMENT_DATA_RETENTION", int), - ("API_LOGS_DATA_RETENTION", int), + ("WORKFLOW_MANAGEMENT", bool), ("WORKFLOW_MANAGEMENT", bool), ] diff --git a/apps/api/karrio/server/settings/constance.py b/apps/api/karrio/server/settings/constance.py index 2acce753f..ec99bc0ce 100644 --- a/apps/api/karrio/server/settings/constance.py +++ b/apps/api/karrio/server/settings/constance.py @@ -1,5 +1,7 @@ """ Dynamic configuration editable on runtime powered by django-constance.""" + from decouple import config +import karrio.server.settings.base as base from karrio.server.settings.email import ( EMAIL_USE_TLS, EMAIL_HOST_USER, @@ -8,9 +10,11 @@ EMAIL_PORT, EMAIL_FROM_ADDRESS, ) +import importlib.util CONSTANCE_BACKEND = "constance.backends.database.DatabaseBackend" CONSTANCE_DATABASE_PREFIX = "constance:core:" + DATA_ARCHIVING_SCHEDULE = config("DATA_ARCHIVING_SCHEDULE", default=168, cast=int) GOOGLE_CLOUD_API_KEY = config("GOOGLE_CLOUD_API_KEY", default="") @@ -23,6 +27,107 @@ SHIPMENT_DATA_RETENTION = config("SHIPMENT_DATA_RETENTION", default=183, cast=int) API_LOGS_DATA_RETENTION = config("API_LOGS_DATA_RETENTION", default=92, cast=int) +# Create feature flags config only for modules that exist +FEATURE_FLAGS_CONFIG = { + "AUDIT_LOGGING": ( + ( + base.AUDIT_LOGGING, + "Audit logging", + bool, + ) + if importlib.util.find_spec("karrio.server.audit") is not None + else None + ), + "ALLOW_SIGNUP": ( + base.ALLOW_SIGNUP, + "Allow signup", + bool, + ), + "ALLOW_ADMIN_APPROVED_SIGNUP": ( + base.ALLOW_ADMIN_APPROVED_SIGNUP, + "Allow admin approved signup", + bool, + ), + "ALLOW_MULTI_ACCOUNT": ( + base.ALLOW_MULTI_ACCOUNT, + "Allow multi account", + bool, + ), + "ADMIN_DASHBOARD": ( + ( + base.ADMIN_DASHBOARD, + "Admin dashboard", + bool, + ) + if importlib.util.find_spec("karrio.server.admin") is not None + else None + ), + "MULTI_ORGANIZATIONS": ( + ( + base.MULTI_ORGANIZATIONS, + "Multi organizations", + bool, + ) + if importlib.util.find_spec("karrio.server.orgs") is not None + else None + ), + "ORDERS_MANAGEMENT": ( + ( + base.ORDERS_MANAGEMENT, + "Orders management", + bool, + ) + if importlib.util.find_spec("karrio.server.orders") is not None + else None + ), + "APPS_MANAGEMENT": ( + ( + base.APPS_MANAGEMENT, + "Apps management", + bool, + ) + if importlib.util.find_spec("karrio.server.apps") is not None + else None + ), + "DOCUMENTS_MANAGEMENT": ( + ( + base.DOCUMENTS_MANAGEMENT, + "Documents management", + bool, + ) + if importlib.util.find_spec("karrio.server.documents") is not None + else None + ), + "DATA_IMPORT_EXPORT": ( + ( + base.DATA_IMPORT_EXPORT, + "Data import export", + bool, + ) + if importlib.util.find_spec("karrio.server.data") is not None + else None + ), + "WORKFLOW_MANAGEMENT": ( + ( + base.WORKFLOW_MANAGEMENT, + "Workflow management", + bool, + ) + if importlib.util.find_spec("karrio.server.automation") is not None + else None + ), + "PERSIST_SDK_TRACING": ( + base.PERSIST_SDK_TRACING, + "Persist SDK tracing", + bool, + ), +} + +# Update fieldsets to only include existing feature flags +FEATURE_FLAGS_FIELDSET = [k for k, v in FEATURE_FLAGS_CONFIG.items() if v is not None] + + +# Filter out None values and update CONSTANCE_CONFIG CONSTANCE_CONFIG = { "EMAIL_USE_TLS": ( EMAIL_USE_TLS, @@ -72,6 +177,7 @@ "API request and SDK tracing logs retention period (in days)", int, ), + **{k: v for k, v in FEATURE_FLAGS_CONFIG.items() if v is not None}, } CONSTANCE_CONFIG_FIELDSETS = { @@ -87,10 +193,11 @@ "GOOGLE_CLOUD_API_KEY", "CANADAPOST_ADDRESS_COMPLETE_API_KEY", ), - "Data retention": ( + "Data Retention": ( "ORDER_DATA_RETENTION", "TRACKER_DATA_RETENTION", "SHIPMENT_DATA_RETENTION", "API_LOGS_DATA_RETENTION", ), + "Feature Flags": tuple(FEATURE_FLAGS_FIELDSET), } diff --git a/apps/dashboard/public/carriers/bokknight_icon.svg b/apps/dashboard/public/carriers/boxknight_icon.svg similarity index 100% rename from apps/dashboard/public/carriers/bokknight_icon.svg rename to apps/dashboard/public/carriers/boxknight_icon.svg diff --git a/apps/dashboard/public/carriers/canadapost_icon.svg b/apps/dashboard/public/carriers/canadapost_icon.svg index 3ab9647d1..0d11e8721 100644 --- a/apps/dashboard/public/carriers/canadapost_icon.svg +++ b/apps/dashboard/public/carriers/canadapost_icon.svg @@ -1 +1,8 @@ - \ No newline at end of file + + + + + \ No newline at end of file diff --git a/apps/dashboard/public/carriers/sendle_icon.svg b/apps/dashboard/public/carriers/sendle_icon.svg index a21de9b5c..1e3a7c902 100644 --- a/apps/dashboard/public/carriers/sendle_icon.svg +++ b/apps/dashboard/public/carriers/sendle_icon.svg @@ -1 +1,6 @@ - \ No newline at end of file + + + + + \ No newline at end of file diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/accounts/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/accounts/page.tsx new file mode 100644 index 000000000..7393b7359 --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/accounts/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/accounts"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/addons/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/addons/page.tsx new file mode 100644 index 000000000..5ec7d4685 --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/addons/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/addons"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/carrier-connections/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/carrier-connections/page.tsx deleted file mode 100644 index 3dcd4413b..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/carrier-connections/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/carrier-connections"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/carriers/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/carriers/page.tsx new file mode 100644 index 000000000..24e76d49c --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/carriers/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/carriers"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/organization-accounts/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/organization-accounts/page.tsx deleted file mode 100644 index d670b9800..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/organization-accounts/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/organization-accounts"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/page.tsx index d75b31927..599026827 100644 --- a/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/page.tsx +++ b/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/page.tsx @@ -1 +1 @@ -export { default } from "@karrio/admin/modules/platform-details"; +export { default } from "@karrio/admin/modules/platform"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/staff/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/staff/page.tsx new file mode 100644 index 000000000..3f6fa8389 --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/staff/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/staff"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/surcharges/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/surcharges/page.tsx deleted file mode 100644 index 15d91a282..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/surcharges/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/surcharges"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/users-permissions/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/users-permissions/page.tsx deleted file mode 100644 index 52d006749..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/[domain]/admin/users-permissions/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/users-permissions"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/accounts/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/accounts/page.tsx new file mode 100644 index 000000000..7393b7359 --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/accounts/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/accounts"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/addons/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/addons/page.tsx new file mode 100644 index 000000000..5ec7d4685 --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/addons/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/addons"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/carrier-connections/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/carrier-connections/page.tsx deleted file mode 100644 index 3dcd4413b..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/carrier-connections/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/carrier-connections"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/carriers/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/carriers/page.tsx new file mode 100644 index 000000000..24e76d49c --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/carriers/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/carriers"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/organization-accounts/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/organization-accounts/page.tsx deleted file mode 100644 index d670b9800..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/organization-accounts/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/organization-accounts"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/page.tsx index d75b31927..599026827 100644 --- a/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/page.tsx +++ b/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/page.tsx @@ -1 +1 @@ -export { default } from "@karrio/admin/modules/platform-details"; +export { default } from "@karrio/admin/modules/platform"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/staff/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/staff/page.tsx new file mode 100644 index 000000000..3f6fa8389 --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/staff/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/staff"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/surcharges/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/surcharges/page.tsx deleted file mode 100644 index 15d91a282..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/surcharges/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/surcharges"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/users-permissions/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/users-permissions/page.tsx deleted file mode 100644 index 52d006749..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/[domain]/test/admin/users-permissions/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/users-permissions"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/admin/accounts/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/admin/accounts/page.tsx new file mode 100644 index 000000000..7393b7359 --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/admin/accounts/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/accounts"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/admin/addons/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/admin/addons/page.tsx new file mode 100644 index 000000000..5ec7d4685 --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/admin/addons/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/addons"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/admin/carrier-connections/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/admin/carrier-connections/page.tsx deleted file mode 100644 index 3dcd4413b..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/admin/carrier-connections/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/carrier-connections"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/admin/carriers/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/admin/carriers/page.tsx new file mode 100644 index 000000000..24e76d49c --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/admin/carriers/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/carriers"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/admin/organization-accounts/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/admin/organization-accounts/page.tsx deleted file mode 100644 index d670b9800..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/admin/organization-accounts/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/organization-accounts"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/admin/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/admin/page.tsx index d75b31927..599026827 100644 --- a/apps/dashboard/src/app/(ee)/(admin)/admin/page.tsx +++ b/apps/dashboard/src/app/(ee)/(admin)/admin/page.tsx @@ -1 +1 @@ -export { default } from "@karrio/admin/modules/platform-details"; +export { default } from "@karrio/admin/modules/platform"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/admin/staff/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/admin/staff/page.tsx new file mode 100644 index 000000000..3f6fa8389 --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/admin/staff/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/staff"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/admin/surcharges/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/admin/surcharges/page.tsx deleted file mode 100644 index 15d91a282..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/admin/surcharges/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/surcharges"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/admin/users-permissions/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/admin/users-permissions/page.tsx deleted file mode 100644 index 52d006749..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/admin/users-permissions/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/users-permissions"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/test/admin/accounts/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/test/admin/accounts/page.tsx new file mode 100644 index 000000000..7393b7359 --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/test/admin/accounts/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/accounts"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/test/admin/addons/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/test/admin/addons/page.tsx new file mode 100644 index 000000000..5ec7d4685 --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/test/admin/addons/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/addons"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/test/admin/carrier-connections/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/test/admin/carrier-connections/page.tsx deleted file mode 100644 index 3dcd4413b..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/test/admin/carrier-connections/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/carrier-connections"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/test/admin/carriers/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/test/admin/carriers/page.tsx new file mode 100644 index 000000000..24e76d49c --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/test/admin/carriers/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/carriers"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/test/admin/organization-accounts/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/test/admin/organization-accounts/page.tsx deleted file mode 100644 index d670b9800..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/test/admin/organization-accounts/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/organization-accounts"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/test/admin/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/test/admin/page.tsx index d75b31927..599026827 100644 --- a/apps/dashboard/src/app/(ee)/(admin)/test/admin/page.tsx +++ b/apps/dashboard/src/app/(ee)/(admin)/test/admin/page.tsx @@ -1 +1 @@ -export { default } from "@karrio/admin/modules/platform-details"; +export { default } from "@karrio/admin/modules/platform"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/test/admin/staff/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/test/admin/staff/page.tsx new file mode 100644 index 000000000..3f6fa8389 --- /dev/null +++ b/apps/dashboard/src/app/(ee)/(admin)/test/admin/staff/page.tsx @@ -0,0 +1 @@ +export { default } from "@karrio/admin/modules/staff"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/test/admin/surcharges/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/test/admin/surcharges/page.tsx deleted file mode 100644 index 15d91a282..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/test/admin/surcharges/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/surcharges"; diff --git a/apps/dashboard/src/app/(ee)/(admin)/test/admin/users-permissions/page.tsx b/apps/dashboard/src/app/(ee)/(admin)/test/admin/users-permissions/page.tsx deleted file mode 100644 index 52d006749..000000000 --- a/apps/dashboard/src/app/(ee)/(admin)/test/admin/users-permissions/page.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default } from "@karrio/admin/modules/users-permissions"; diff --git a/ee/packages/console/apis/stripe-webhook.ts b/ee/packages/console/apis/stripe-webhook.ts index cc0ccb258..2e71b1e47 100644 --- a/ee/packages/console/apis/stripe-webhook.ts +++ b/ee/packages/console/apis/stripe-webhook.ts @@ -16,24 +16,24 @@ export async function POST(req: Request) { switch (event.type) { case "checkout.session.completed": { const session = event.data.object; - const organizationId = session.metadata?.organizationId || null; + const orgId = session.metadata?.orgId || null; - if (!organizationId) { + if (!orgId) { throw new Error("Organization ID is required"); } // Update the organization with the stripeCustomerId await prisma.organization.update({ - where: { id: organizationId }, + where: { id: orgId }, data: { stripeCustomerId: session.customer as string, }, }); await prisma.subscription.upsert({ - where: { organizationId }, + where: { orgId }, create: { - organizationId, + orgId, stripeSubscriptionId: session.subscription as string, stripePriceId: session.metadata?.priceId, status: "active", diff --git a/ee/packages/console/components/payment-method-form.tsx b/ee/packages/console/components/payment-method-form.tsx index 2a7fef4bc..dd8d83765 100644 --- a/ee/packages/console/components/payment-method-form.tsx +++ b/ee/packages/console/components/payment-method-form.tsx @@ -5,13 +5,13 @@ import { trpc } from "@karrio/console/trpc/client"; import { useState } from "react"; interface PaymentMethodFormProps { - organizationId: string; + orgId: string; onSuccess: () => void; clientSecret: string | null; } export function PaymentMethodForm({ - organizationId, + orgId, onSuccess, clientSecret, }: PaymentMethodFormProps) { @@ -40,11 +40,9 @@ export function PaymentMethodForm({ try { // First, create a setup intent - const { setupIntent: clientSecret } = await createSetupIntent.mutateAsync( - { - organizationId, - }, - ); + const { setupIntent: clientSecret } = await createSetupIntent.mutateAsync({ + orgId, + }); if (!clientSecret) { throw new Error("Failed to create setup intent"); @@ -70,7 +68,7 @@ export function PaymentMethodForm({ // Update the organization's payment method await updatePaymentMethod.mutateAsync({ - organizationId, + orgId, paymentMethodId: setupIntent.payment_method as string, }); diff --git a/ee/packages/console/components/pricing-section.tsx b/ee/packages/console/components/pricing-section.tsx new file mode 100644 index 000000000..5c0ed200b --- /dev/null +++ b/ee/packages/console/components/pricing-section.tsx @@ -0,0 +1,225 @@ +"use client"; + +import { Button } from "@karrio/insiders/components/ui/button"; +import { Check } from "lucide-react"; +import { useState } from "react"; + +type PricingFeature = { + text: string; + soon?: boolean; +}; + +type PricingPlan = { + name: string; + description: string; + price: string | "Contact us"; + priceDetail?: string; + popular?: boolean; + features: PricingFeature[]; + button: { + text: string; + variant?: "default" | "outline"; + }; +}; + +const PRICING_PLANS: Record = { + insiders: { + cloud: { + name: "Insiders", + description: "Advanced features included. Dedicated support team. Scale your operations.", + price: "$299", + priceDetail: "/month", + popular: true, + button: { + text: "Join Waitlist", + }, + features: [ + { text: "10,000 labels/trackers a month" }, + { text: "$0.04 overage beyond" }, + { text: "Multi-tenant & User management" }, + { text: "Email & Slack support" }, + { text: "Customizable dashboard", soon: true }, + { text: "Platform Admin dashboard" }, + { text: "Platform APIs" }, + ], + }, + selfHosted: { + name: "Insiders", + description: "Advanced features included. Dedicated support team. Scale your operations.", + price: "$299", + priceDetail: "/month", + popular: true, + button: { + text: "Join Now", + }, + features: [ + { text: "Unlimited labels/trackers a month" }, + { text: "No overages" }, + { text: "Multi-tenant & User management" }, + { text: "Email & Slack support" }, + { text: "Customizable dashboard", soon: true }, + { text: "Platform Admin dashboard" }, + { text: "Platform APIs" }, + ], + }, + }, + scale: { + cloud: { + name: "Scale", + description: "High-volume enterprise features. Premium support included. Enterprise-grade security.", + price: "$2,499", + priceDetail: "/month", + button: { + text: "Get Started", + variant: "outline", + }, + features: [ + { text: "100,000 labels/trackers a month" }, + { text: "$0.02 overage beyond" }, + { text: "One-on-one developer calls" }, + { text: "Up to 5 new carrier integrations/month" }, + { text: "Expedited features and integrations" }, + { text: "SLA (99.999% uptime)" }, + { text: "Compliance Check SOC2, HIPAA", soon: true }, + ], + }, + selfHosted: { + name: "Scale", + description: "High-volume enterprise features. Premium support included. Enterprise-grade security.", + price: "$2,499", + priceDetail: "/month", + button: { + text: "Get Started", + variant: "outline", + }, + features: [ + { text: "Unlimited labels/trackers a month" }, + { text: "No overages" }, + { text: "One-on-one developer calls" }, + { text: "Up to 5 new carrier integrations/month" }, + { text: "Expedited features and integrations" }, + { text: "SLA (99.999% uptime)" }, + { text: "Compliance Check SOC2, HIPAA", soon: true }, + ], + }, + }, + enterprise: { + cloud: { + name: "Enterprise", + description: "Custom-tailored solution. Unlimited shipping volume. Dedicated enterprise support.", + price: "Contact us", + button: { + text: "Contact Sales", + variant: "outline", + }, + features: [ + { text: "Unlimited labels/trackers a month" }, + { text: "No overages" }, + { text: "One-on-one developer calls" }, + { text: "Dedicated carrier onboarding support" }, + { text: "Expedited features and integrations" }, + { text: "SLA (99.999% uptime)" }, + { text: "Volume Discount" }, + { text: "Compliance Check SOC2, HIPAA", soon: true }, + ], + }, + }, +}; + +function PricingCard({ plan, className = "" }: { plan: PricingPlan; className?: string }) { + return ( +
+ {plan.popular && ( +
+ Most Popular +
+ )} +
+

{plan.name}

+
+ {plan.price} + {plan.priceDetail && {plan.priceDetail}} +
+

{plan.description}

+ +
+ +
+ ); +} + +export function PricingSection() { + const [deploymentType, setDeploymentType] = useState<"cloud" | "self-hosted">("cloud"); + + return ( +
+
+
+
+
+
+
Pricing
+

+ Simple, transparent pricing +

+

+ Choose the plan that best fits your business needs. All plans include access to our core features. +

+
+ +
+
+ + +
+
+ +
+ {Object.entries(PRICING_PLANS).map(([key, { cloud, selfHosted: selfHosted }]) => { + const plan = deploymentType === "cloud" ? cloud : (selfHosted ?? cloud); + return ( + + ); + })} +
+
+
+ ); +} diff --git a/ee/packages/console/components/pricing-toggle.tsx b/ee/packages/console/components/pricing-toggle.tsx new file mode 100644 index 000000000..857020e55 --- /dev/null +++ b/ee/packages/console/components/pricing-toggle.tsx @@ -0,0 +1,36 @@ +import * as React from "react"; +import { cn } from "@karrio/insiders/lib/utils"; + +interface PricingToggleProps { + value: "cloud" | "self-hosted"; + onChange: (value: "cloud" | "self-hosted") => void; +} + +export function PricingToggle({ value, onChange }: PricingToggleProps) { + return ( +
+ + +
+ ); +} diff --git a/ee/packages/console/components/roadmap-section.tsx b/ee/packages/console/components/roadmap-section.tsx new file mode 100644 index 000000000..894c46ba4 --- /dev/null +++ b/ee/packages/console/components/roadmap-section.tsx @@ -0,0 +1,242 @@ +"use client" + +import { useState } from "react"; +import { ChevronRight, Check } from "lucide-react"; + +interface RoadmapSubItem { + title: string; + status: "completed" | "in_progress" | "planned"; +} + +interface RoadmapItem { + title: string; + status: "in_progress" | "planned" | "completed"; + description: string; + items: RoadmapSubItem[]; +} + +const ROADMAP_ITEMS: RoadmapItem[] = [ + { + title: "Admin Dashboard", + status: "in_progress", + description: "Comprehensive admin tools for platform and carrier management", + items: [ + { title: "Platform API", status: "completed" }, + { title: "System Carrier Management & Rate sheets", status: "in_progress" }, + { title: "Connected Account Management", status: "in_progress" }, + { title: "Markups Management", status: "planned" }, + { title: "Docs", status: "planned" } + ] + }, + { + title: "Karrio Automation", + status: "in_progress", + description: "Advanced automation tools for shipping workflows and integrations", + items: [ + { title: "Finalize Cron Job support", status: "completed" }, + { title: "Shipping Rules API", status: "in_progress" }, + { title: "Shipping Rules Dashboard", status: "in_progress" }, + { title: "Finalize Connections Management", status: "planned" }, + { title: "Finalize Integration Presets Management", status: "planned" }, + { title: "Docs", status: "planned" } + ] + }, + { + title: "Customizable Shipper Dashboard", + status: "planned", + description: "Flexible and customizable dashboard solutions for shippers", + items: [ + { title: "Portal app template", status: "planned" }, + { title: "Reusable Elements", status: "planned" } + ] + }, + { + title: "Karrio CLI", + status: "planned", + description: "Command-line tools for developers and integrations", + items: [ + { title: "Finalize API reader", status: "planned" }, + { title: "Finalize Carrier integration cli", status: "planned" } + ] + }, + { + title: "Karrio Enterprise Features", + status: "planned", + description: "Advanced features for enterprise customers", + items: [ + { title: "SSO", status: "planned" }, + { title: "Audit Log (API + Management UI)", status: "planned" }, + { title: "Advanced Analytics", status: "planned" }, + { title: "Compliance Check", status: "planned" } + ] + }, + { + title: "Karrio Dashboard Apps", + status: "planned", + description: "Extensible app ecosystem for the Karrio platform", + items: [ + { title: "Embedded apps toolkit", status: "planned" }, + { title: "Billing reconciliation app", status: "planned" }, + { title: "Pickup management app", status: "planned" } + ] + }, + { + title: "Carrier On-boarding Dev tool", + status: "planned", + description: "AI-powered tools for carrier integration", + items: [ + { title: "AI assisted carrier integration", status: "planned" }, + { title: "Onboard Lifecycle management", status: "planned" } + ] + }, + { + title: "Carrier Dashboard Mode", + status: "planned", + description: "Advanced carrier management and customization tools", + items: [ + { title: "Generic carrier hooks", status: "planned" }, + { title: "Custom Tracking Event mapping", status: "planned" }, + { title: "Advanced Label designer", status: "planned" } + ] + } +]; + +function StatusIndicator({ status }: { status: RoadmapSubItem["status"] }) { + if (status === "completed") { + return ( +
+ +
+ ); + } + + return ( +
+
+
+ ); +} + +export function RoadmapSection() { + const [selectedItem, setSelectedItem] = useState(ROADMAP_ITEMS[0]); + + return ( +
+
+
+
+
+
+
Product Roadmap
+

+ Building the future of logistics +

+

+ Our vision for revolutionizing the shipping and logistics industry through continuous innovation and development. +

+
+ +
+
+ {ROADMAP_ITEMS.map((item) => ( +
setSelectedItem(item)} + > +
+
+

+ {item.title} +

+
+ +
+ ))} +
+ +
+ {selectedItem && ( +
+
+
+
+ {selectedItem.status === "in_progress" + ? "In Progress" + : selectedItem.status === "completed" + ? "Completed" + : "Planned"} +
+
+
+
+
+ + {selectedItem.items.filter(i => i.status === "completed").length} completed + +
+
+
+ + {selectedItem.items.filter(i => i.status === "in_progress").length} in progress + +
+
+
+ +

{selectedItem.title}

+

{selectedItem.description}

+ +
+
+

Features

+
+ {selectedItem.items.map((item, index) => ( +
+
+ +
+

{item.title}

+
+
+
+ ))} +
+
+
+
+ )} +
+
+
+
+ ); +} diff --git a/ee/packages/console/modules/landing/index.tsx b/ee/packages/console/modules/landing/index.tsx index 1518247de..d6b71277c 100644 --- a/ee/packages/console/modules/landing/index.tsx +++ b/ee/packages/console/modules/landing/index.tsx @@ -10,8 +10,9 @@ import { Globe, Layers, } from "lucide-react"; -import { CarrierNetwork } from "@karrio/console/components/features-illustrations/carrier-network"; import { FeatureShowcase } from "@karrio/console/components/feature-showcase"; +import { RoadmapSection } from "@karrio/console/components/roadmap-section"; +import { PricingSection } from "@karrio/console/components/pricing-section"; import { CodePreview } from "@karrio/console/components/code-preview"; import { FeatureTabs } from "@karrio/console/components/feature-tabs"; import { CTASection } from "@karrio/console/components/cta-section"; @@ -322,219 +323,176 @@ export default async function LandingPage() {
- {/* How It Works Section */} + {/* Use Cases Section */}
-
How it works
+
Use Cases

- Build your shipping operations with speed and flexibility + Tailored solutions for specialized shipping needs

- Offer your users a great experience from day one with fast - onboarding, accurate dashboards, and useful workflows – such as - returns, tracking notifications, and carrier management. + From marketplaces to enterprise logistics, Karrio provides a customizable platform to meet the unique requirements of different business models and industries.

- Karrio hosted shipping interface -
- ), - }, - { - label: "Embedded", - value: "embedded", - content: ( -
- Karrio embedded shipping components -
- ), - }, - { - label: "API", - value: "api", - content: ( -
-
-
-                          {`// Create a new shipment
-const shipment = await karrio.shipments.create({
-  service: "fedex_ground",
-  shipper: {
-    company_name: "ACME Inc",
-    address_line1: "123 Shipping St",
-    postal_code: "V6M2V9",
-    city: "Vancouver",
-    country_code: "CA",
-  },
-  recipient: {
-    name: "John Doe",
-    address_line1: "456 Delivery Ave",
-    postal_code: "27401",
-    city: "Greensboro",
-    country_code: "US",
-  },
-  parcels: [{
-    weight: 1.5,
-    weight_unit: "KG",
-    width: 20,
-    height: 10,
-    length: 15,
-    dimension_unit: "CM"
-  }]
-});`}
-                        
+
+
+
    +
  • +
    +
    +
    + API-first platform for seamless integration +
  • +
  • +
    +
    +
    + Real-time visibility and tracking capabilities +
  • +
  • +
    +
    +
    + Automated documentation and customs compliance +
  • +
  • +
    +
    +
    + Enhanced partner collaboration tools +
  • +
+
+
+ Logistics Providers illustration
), - }, + } ]} /> - Karrio hosted dashboard -
- ), - }, - { - label: "Embedded", - value: "embedded", + label: "Overview", + value: "overview", content: ( -
- Karrio embedded dashboard components -
- ), - }, - { - label: "API", - value: "api", - content: ( -
-
-
-                          {`// Fetch shipment details and tracking
-const shipment = await karrio.shipments.retrieve('shp_123');
-const tracking = await karrio.tracking.get(shipment.tracking_number);
-
-console.log(tracking.status); // "in_transit"
-console.log(tracking.estimated_delivery); // "2024-01-28"
-console.log(tracking.events); // Array of tracking events`}
-                        
+
+
+
    +
  • +
    +
    +
    + Multi-carrier rate shopping and automated carrier selection +
  • +
  • +
    +
    +
    + Automated label generation and tracking updates +
  • +
  • +
    +
    +
    + Seamless integration with major e-commerce platforms +
  • +
  • +
    +
    +
    + Advanced analytics and reporting for merchant insights +
  • +
+
+
+ Marketplace & OMS illustration
), - }, + } ]} /> - Karrio hosted carrier account management -
- ), - }, - { - label: "Embedded", - value: "embedded", + label: "Overview", + value: "overview", content: ( -
- Karrio embedded carrier account components -
- ), - }, - { - label: "API", - value: "api", - content: ( -
-
-
-                          {`// Add a new carrier account
-const carrierAccount = await karrio.carrierAccounts.create({
-  carrier: "fedex",
-  account_number: "123456789",
-  account_country: "US",
-  test_mode: false,
-  active: true,
-  credentials: {
-    user_key: "YOUR_FEDEX_USER_KEY",
-    password: "YOUR_FEDEX_PASSWORD",
-    meter_number: "YOUR_FEDEX_METER_NUMBER",
-    account_number: "YOUR_FEDEX_ACCOUNT_NUMBER"
-  }
-});
-
-console.log(carrierAccount.id); // "ca_123456789"
-console.log(carrierAccount.status); // "active"`}
-                        
+
+
+
    +
  • +
    +
    +
    + Advanced security features and compliance controls +
  • +
  • +
    +
    +
    + Specialized handling for sensitive shipments +
  • +
  • +
    +
    +
    + Custom workflows and approval processes +
  • +
  • +
    +
    +
    + Dedicated support and SLA guarantees +
  • +
+
+
+ Enterprise Solutions illustration
), - }, + } ]} />
@@ -714,6 +672,72 @@ shipment = karrio.shipments.create(
+ {/* Roadmap Section */} + + + {/* Pricing Section */} + + + {/* FAQ Section */} +
+
+
+
+
+
+
FAQ
+

+ Frequently Asked Questions +

+

+ Everything you need to know about Karrio and our services. +

+
+
+
+
+

How does Karrio handle carrier integration?

+

+ Karrio provides a unified API that abstracts away the complexity of individual carrier integrations. We handle the maintenance, updates, and certification requirements for each carrier, allowing you to focus on your core business. +

+
+
+

What carriers do you support?

+

+ We support 30+ major carriers globally, including USPS, FedEx, UPS, DHL, and many regional carriers. Our platform is continuously expanding to include more carriers based on customer needs. +

+
+
+

Is Karrio suitable for small businesses?

+

+ Yes! Our platform is designed to scale with your business. Start with our free tier and upgrade as your shipping needs grow. We offer solutions for businesses of all sizes. +

+
+
+
+
+

How does pricing work?

+

+ Our pricing is based on shipping volume and features needed. We offer a free tier for small businesses, a professional plan for growing companies, and custom enterprise solutions for large-scale operations. +

+
+
+

Can I use my existing carrier accounts?

+

+ Yes, you can connect your existing carrier accounts to Karrio. We provide easy-to-use tools for managing multiple carrier accounts and credentials in one place. +

+
+
+

What kind of support do you offer?

+

+ We provide different levels of support based on your plan. This includes community support, email support, priority support with faster response times, and dedicated support teams for enterprise customers. +

+
+
+
+
+
+ {/* CTA Section */} diff --git a/ee/packages/console/modules/organizations/billing/index.tsx b/ee/packages/console/modules/organizations/billing/index.tsx index a8da4a3a5..988ad9934 100644 --- a/ee/packages/console/modules/organizations/billing/index.tsx +++ b/ee/packages/console/modules/organizations/billing/index.tsx @@ -67,16 +67,16 @@ export default function BillingPage({ params }: { params: { orgId: string } }) { const router = useRouter(); const utils = trpc.useUtils(); const { data: subscription } = trpc.billing.getSubscription.useQuery({ - organizationId: params.orgId, + orgId: params.orgId, }); const { data: billingInfo } = trpc.billing.getBillingInfo.useQuery({ - organizationId: params.orgId, + orgId: params.orgId, }); const { data: currentPlan } = trpc.billing.getPlan.useQuery({ - organizationId: params.orgId, + orgId: params.orgId, }); const { data: invoices } = trpc.billing.getInvoices.useQuery({ - organizationId: params.orgId, + orgId: params.orgId, }); const updateBilling = trpc.billing.updateBillingInfo.useMutation(); const createSetupIntent = trpc.billing.createSetupIntent.useMutation(); @@ -98,7 +98,7 @@ export default function BillingPage({ params }: { params: { orgId: string } }) { const [isMounted, setIsMounted] = useState(false); const { data: paymentMethods } = trpc.billing.getPaymentMethods.useQuery({ - organizationId: params.orgId, + orgId: params.orgId, }); const setDefaultPaymentMethod = trpc.billing.setDefaultPaymentMethod.useMutation(); @@ -124,9 +124,17 @@ export default function BillingPage({ params }: { params: { orgId: string } }) { const [showPlanSelection, setShowPlanSelection] = useState(false); const { data: plans } = trpc.billing.getPlans.useQuery(); + const refreshAllResources = () => { + utils.billing.getSubscription.invalidate(); + utils.billing.getBillingInfo.invalidate(); + utils.billing.getPlan.invalidate(); + utils.billing.getInvoices.invalidate(); + utils.billing.getPaymentMethods.invalidate(); + }; + const createSubscription = trpc.billing.createSubscription.useMutation({ onSuccess: () => { - utils.billing.getSubscription.invalidate(); + refreshAllResources(); setShowPlanSelection(false); toast({ title: "Success", @@ -199,7 +207,7 @@ export default function BillingPage({ params }: { params: { orgId: string } }) { const handleUpdateBilling = async () => { try { await updateBilling.mutateAsync({ - organizationId: params.orgId, + orgId: params.orgId, email: billingEmail, address: billingAddress, }); @@ -220,7 +228,7 @@ export default function BillingPage({ params }: { params: { orgId: string } }) { const handleUpdateTaxId = async () => { try { await updateBilling.mutateAsync({ - organizationId: params.orgId, + orgId: params.orgId, taxId: { type: taxIdType, value: taxIdNumber, @@ -243,7 +251,7 @@ export default function BillingPage({ params }: { params: { orgId: string } }) { const handleAddCard = async () => { try { const setupIntent = await createSetupIntent.mutateAsync({ - organizationId: params.orgId, + orgId: params.orgId, }); setSetupIntentSecret(setupIntent.setupIntent); @@ -260,7 +268,7 @@ export default function BillingPage({ params }: { params: { orgId: string } }) { const handleSetDefaultPaymentMethod = async (paymentMethodId: string) => { try { await setDefaultPaymentMethod.mutateAsync({ - organizationId: params.orgId, + orgId: params.orgId, paymentMethodId, }); toast({ @@ -280,7 +288,7 @@ export default function BillingPage({ params }: { params: { orgId: string } }) { const handleDeletePaymentMethod = async (paymentMethodId: string) => { try { await deletePaymentMethod.mutateAsync({ - organizationId: params.orgId, + orgId: params.orgId, paymentMethodId, }); } catch (error) { @@ -305,7 +313,7 @@ export default function BillingPage({ params }: { params: { orgId: string } }) { try { await createSubscription.mutateAsync({ - organizationId: params.orgId, + orgId: params.orgId, priceId: selectedPlan, }); } catch (error: any) { @@ -457,7 +465,7 @@ export default function BillingPage({ params }: { params: { orgId: string } }) { onValueChange={async (value) => { try { await retrySubscriptionPayment.mutateAsync({ - organizationId: params.orgId, + orgId: params.orgId, paymentMethodId: value, }); utils.billing.getSubscription.invalidate(); @@ -573,7 +581,7 @@ export default function BillingPage({ params }: { params: { orgId: string } }) { variant="outline" onClick={() => reactivateSubscription.mutateAsync({ - organizationId: params.orgId, + orgId: params.orgId, }) } disabled={reactivateSubscription.status === "loading"} @@ -957,8 +965,9 @@ export default function BillingPage({ params }: { params: { orgId: string } }) { { + refreshAllResources(); setShowPaymentForm(false); router.refresh(); }} @@ -1005,7 +1014,7 @@ export default function BillingPage({ params }: { params: { orgId: string } }) { className="bg-destructive text-destructive-foreground hover:bg-destructive/90" onClick={() => { cancelSubscription.mutateAsync({ - organizationId: params.orgId, + orgId: params.orgId, }); setShowCancelDialog(false); }} diff --git a/ee/packages/console/modules/organizations/settings/index.tsx b/ee/packages/console/modules/organizations/settings/index.tsx index e6cb47c9e..c1e1f5e81 100644 --- a/ee/packages/console/modules/organizations/settings/index.tsx +++ b/ee/packages/console/modules/organizations/settings/index.tsx @@ -173,7 +173,7 @@ export default function SettingsPage({ + )} {currentProject?.status === "UNREACHABLE" && ( diff --git a/ee/packages/console/modules/projects/index.tsx b/ee/packages/console/modules/projects/index.tsx index 4e367e09b..4ef22d315 100644 --- a/ee/packages/console/modules/projects/index.tsx +++ b/ee/packages/console/modules/projects/index.tsx @@ -14,7 +14,7 @@ export default function Dashboard() { const router = useRouter(); const orgId = params.orgId as string; const { data, isLoading } = trpc.projects.getAll.useQuery({ - organizationId: orgId, + orgId: orgId, }); const { projects, limit, count } = data || { projects: [], diff --git a/ee/packages/console/modules/projects/settings/index.tsx b/ee/packages/console/modules/projects/settings/index.tsx index 27dcb1e54..fec455440 100644 --- a/ee/packages/console/modules/projects/settings/index.tsx +++ b/ee/packages/console/modules/projects/settings/index.tsx @@ -61,7 +61,7 @@ export default function SettingsPage({ const utils = trpc.useUtils(); const { data: currentProject } = trpc.projects.get.useQuery({ id: params.projectId, - organizationId: params.orgId, + orgId: params.orgId, }); const { data: tenant } = trpc.projects.tenant.get.useQuery({ projectId: params.projectId, @@ -69,7 +69,7 @@ export default function SettingsPage({ const updateProject = trpc.projects.update.useMutation<{ id: string; name: string; - organizationId: string; + orgId: string; }>({ onSuccess: () => { utils.projects.get.invalidate(); @@ -156,7 +156,7 @@ export default function SettingsPage({ onSuccess: () => { utils.projects.get.invalidate({ id: params.projectId, - organizationId: params.orgId, + orgId: params.orgId, }); toast({ title: "Success", @@ -180,7 +180,7 @@ export default function SettingsPage({ await updateProject.mutateAsync({ id: params.projectId, name: projectName, - organizationId: params.orgId, + orgId: params.orgId, }); } catch (error) { // Error is handled by the mutation callbacks diff --git a/ee/packages/console/prisma/migrations/20241221151844_add_project_status/migration.sql b/ee/packages/console/prisma/migrations/20241221151844_add_project_status/migration.sql deleted file mode 100644 index af5102c8b..000000000 --- a/ee/packages/console/prisma/migrations/20241221151844_add_project_status/migration.sql +++ /dev/null @@ -1 +0,0 @@ --- This is an empty migration. \ No newline at end of file diff --git a/ee/packages/console/prisma/migrations/20241220231237_initial/migration.sql b/ee/packages/console/prisma/migrations/20250131073742_initial/migration.sql similarity index 81% rename from ee/packages/console/prisma/migrations/20241220231237_initial/migration.sql rename to ee/packages/console/prisma/migrations/20250131073742_initial/migration.sql index d3012670a..6775bafa9 100644 --- a/ee/packages/console/prisma/migrations/20241220231237_initial/migration.sql +++ b/ee/packages/console/prisma/migrations/20250131073742_initial/migration.sql @@ -1,3 +1,6 @@ +-- CreateEnum +CREATE TYPE "ProjectStatus" AS ENUM ('PENDING', 'DEPLOYING', 'ACTIVE', 'FAILED', 'UNREACHABLE', 'DELETED'); + -- CreateTable CREATE TABLE "User" ( "id" TEXT NOT NULL, @@ -78,7 +81,7 @@ CREATE TABLE "Organization" ( -- CreateTable CREATE TABLE "OrganizationMembership" ( "id" TEXT NOT NULL, - "organizationId" TEXT NOT NULL, + "orgId" TEXT NOT NULL, "userId" TEXT NOT NULL, "role" TEXT NOT NULL, @@ -89,9 +92,14 @@ CREATE TABLE "OrganizationMembership" ( CREATE TABLE "Project" ( "id" TEXT NOT NULL, "name" TEXT NOT NULL, - "organizationId" TEXT NOT NULL, + "orgId" TEXT NOT NULL, "tenantId" TEXT, "tenantApiKey" TEXT, + "status" "ProjectStatus" NOT NULL DEFAULT 'PENDING', + "statusMessage" TEXT, + "deploymentLogs" JSONB, + "lastPing" TIMESTAMP(3), + "metadata" JSONB, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, @@ -101,7 +109,7 @@ CREATE TABLE "Project" ( -- CreateTable CREATE TABLE "Subscription" ( "id" TEXT NOT NULL, - "organizationId" TEXT NOT NULL, + "orgId" TEXT NOT NULL, "stripePriceId" TEXT, "stripeSubscriptionId" TEXT, "status" TEXT NOT NULL, @@ -119,7 +127,7 @@ CREATE TABLE "OrganizationInvitation" ( "email" TEXT NOT NULL, "token" TEXT NOT NULL, "expires" TIMESTAMP(3) NOT NULL, - "organizationId" TEXT NOT NULL, + "orgId" TEXT NOT NULL, "inviterId" TEXT NOT NULL, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, @@ -146,13 +154,13 @@ CREATE UNIQUE INDEX "Authenticator_credentialID_key" ON "Authenticator"("credent CREATE UNIQUE INDEX "Organization_stripeCustomerId_key" ON "Organization"("stripeCustomerId"); -- CreateIndex -CREATE UNIQUE INDEX "OrganizationMembership_organizationId_userId_key" ON "OrganizationMembership"("organizationId", "userId"); +CREATE UNIQUE INDEX "OrganizationMembership_orgId_userId_key" ON "OrganizationMembership"("orgId", "userId"); -- CreateIndex CREATE UNIQUE INDEX "Project_tenantId_key" ON "Project"("tenantId"); -- CreateIndex -CREATE UNIQUE INDEX "Subscription_organizationId_key" ON "Subscription"("organizationId"); +CREATE UNIQUE INDEX "Subscription_orgId_key" ON "Subscription"("orgId"); -- CreateIndex CREATE UNIQUE INDEX "Subscription_stripeSubscriptionId_key" ON "Subscription"("stripeSubscriptionId"); @@ -161,7 +169,7 @@ CREATE UNIQUE INDEX "Subscription_stripeSubscriptionId_key" ON "Subscription"("s CREATE UNIQUE INDEX "OrganizationInvitation_token_key" ON "OrganizationInvitation"("token"); -- CreateIndex -CREATE INDEX "OrganizationInvitation_organizationId_idx" ON "OrganizationInvitation"("organizationId"); +CREATE INDEX "OrganizationInvitation_orgId_idx" ON "OrganizationInvitation"("orgId"); -- CreateIndex CREATE INDEX "OrganizationInvitation_inviterId_idx" ON "OrganizationInvitation"("inviterId"); @@ -176,19 +184,19 @@ ALTER TABLE "Session" ADD CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId" ALTER TABLE "Authenticator" ADD CONSTRAINT "Authenticator_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "OrganizationMembership" ADD CONSTRAINT "OrganizationMembership_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "OrganizationMembership" ADD CONSTRAINT "OrganizationMembership_orgId_fkey" FOREIGN KEY ("orgId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "OrganizationMembership" ADD CONSTRAINT "OrganizationMembership_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "Project" ADD CONSTRAINT "Project_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "Project" ADD CONSTRAINT "Project_orgId_fkey" FOREIGN KEY ("orgId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "Subscription" ADD CONSTRAINT "Subscription_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "Subscription" ADD CONSTRAINT "Subscription_orgId_fkey" FOREIGN KEY ("orgId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "OrganizationInvitation" ADD CONSTRAINT "OrganizationInvitation_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "OrganizationInvitation" ADD CONSTRAINT "OrganizationInvitation_orgId_fkey" FOREIGN KEY ("orgId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "OrganizationInvitation" ADD CONSTRAINT "OrganizationInvitation_inviterId_fkey" FOREIGN KEY ("inviterId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/ee/packages/console/prisma/schema.prisma b/ee/packages/console/prisma/schema.prisma index 276c8dccf..4fb471849 100644 --- a/ee/packages/console/prisma/schema.prisma +++ b/ee/packages/console/prisma/schema.prisma @@ -101,14 +101,14 @@ model Organization { } model OrganizationMembership { - id String @id @default(cuid()) - organizationId String - userId String - role String // "OWNER" | "MEMBER" - organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - - @@unique([organizationId, userId]) + id String @id @default(cuid()) + orgId String + userId String + role String // "OWNER" | "MEMBER" + organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade) + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + + @@unique([orgId, userId]) } enum ProjectStatus { @@ -123,7 +123,7 @@ enum ProjectStatus { model Project { id String @id @default(cuid()) name String - organizationId String + orgId String tenantId String? @unique // Karrio tenant ID tenantApiKey String? status ProjectStatus @default(PENDING) @@ -133,13 +133,13 @@ model Project { metadata Json? // Additional metadata createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) + organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade) } model Subscription { id String @id @default(cuid()) - organizationId String @unique - organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) + orgId String @unique + organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade) stripePriceId String? stripeSubscriptionId String? @unique status String @@ -150,17 +150,17 @@ model Subscription { } model OrganizationInvitation { - id String @id @default(cuid()) - email String - token String @unique - expires DateTime - organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) - organizationId String - inviter User @relation(fields: [inviterId], references: [id]) - inviterId String - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - @@index([organizationId]) + id String @id @default(cuid()) + email String + token String @unique + expires DateTime + organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade) + orgId String + inviter User @relation(fields: [inviterId], references: [id]) + inviterId String + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@index([orgId]) @@index([inviterId]) } diff --git a/ee/packages/console/trpc/middleware.ts b/ee/packages/console/trpc/middleware.ts index 42f89af03..4f9d4f109 100644 --- a/ee/packages/console/trpc/middleware.ts +++ b/ee/packages/console/trpc/middleware.ts @@ -21,14 +21,14 @@ export const isAuthed = middleware(async ({ ctx, next }) => { export const requireRole = (roles: string[]) => middleware(async ({ ctx, next, input }) => { const session = ctx.session as Session | null; - const reqInput = input as { orgId?: string; organizationId?: string }; - const organizationId = reqInput?.orgId || reqInput?.organizationId; + const reqInput = input as { orgId?: string }; + const orgId = reqInput?.orgId; if (!session?.user) { throw new TRPCError({ code: "UNAUTHORIZED" }); } - if (!organizationId) { + if (!orgId) { throw new TRPCError({ code: "BAD_REQUEST", message: "Organization ID is required", @@ -38,8 +38,8 @@ export const requireRole = (roles: string[]) => // Get user's role in this specific organization const membership = await prisma.organizationMembership.findUnique({ where: { - organizationId_userId: { - organizationId, + orgId_userId: { + orgId, userId: session.user.id, }, }, @@ -52,17 +52,23 @@ export const requireRole = (roles: string[]) => }); } - return next(); + return next({ + ctx: { + ...ctx, + session, + user: session.user, + }, + }); }); -export const requireSubscription = (organizationId: string) => +export const requireSubscription = (orgId: string) => middleware(async ({ ctx, next }) => { if (!ctx.session) { throw new TRPCError({ code: "UNAUTHORIZED" }); } const org = await prisma.organization.findUnique({ - where: { id: organizationId }, + where: { id: orgId }, include: { subscription: true }, }); diff --git a/ee/packages/console/trpc/router.ts b/ee/packages/console/trpc/router.ts index 1e40c04ff..7276e75ac 100644 --- a/ee/packages/console/trpc/router.ts +++ b/ee/packages/console/trpc/router.ts @@ -118,16 +118,16 @@ export const appRouter = router({ }), update: protectedProcedure - .use(requireRole(["OWNER", "ADMIN"])) .input( z.object({ - organizationId: z.string(), + orgId: z.string(), name: z.string(), }), ) + .use(requireRole(["OWNER", "ADMIN"])) .mutation(({ input }) => { return prisma.organization.update({ - where: { id: input.organizationId }, + where: { id: input.orgId }, data: { name: input.name }, }); }), @@ -136,23 +136,23 @@ export const appRouter = router({ .input(z.object({ orgId: z.string() })) .query(async ({ input }) => { return prisma.organizationMembership.findMany({ - where: { organizationId: input.orgId }, + where: { orgId: input.orgId }, include: { user: true }, }); }), inviteMember: protectedProcedure - .use(requireRole(["OWNER"])) .input( z.object({ - organizationId: z.string(), + orgId: z.string(), email: z.string().email(), }), ) + .use(requireRole(["OWNER"])) .mutation(async ({ input, ctx }) => { const session = ctx.session as Session; const organization = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, include: { subscription: true }, }); @@ -166,8 +166,8 @@ export const appRouter = router({ // Check if user is already a member const existingMember = await prisma.organizationMembership.findUnique({ where: { - organizationId_userId: { - organizationId: input.organizationId, + orgId_userId: { + orgId: input.orgId, userId: session.user.id, }, }, @@ -191,7 +191,7 @@ export const appRouter = router({ email: input.email, token, expires, - organizationId: input.organizationId, + orgId: input.orgId, inviterId: session.user.id, }, }); @@ -242,7 +242,7 @@ export const appRouter = router({ await prisma.$transaction([ prisma.organizationMembership.create({ data: { - organizationId: invitation.organizationId, + orgId: invitation.orgId, userId: session.user.id, role: "MEMBER", }, @@ -256,18 +256,18 @@ export const appRouter = router({ }), removeMember: protectedProcedure - .use(requireRole(["OWNER", "ADMIN"])) .input( z.object({ - organizationId: z.string(), + orgId: z.string(), userId: z.string(), }), ) + .use(requireRole(["OWNER", "ADMIN"])) .mutation(async ({ input }) => { return prisma.organizationMembership.delete({ where: { - organizationId_userId: { - organizationId: input.organizationId, + orgId_userId: { + orgId: input.orgId, userId: input.userId, }, }, @@ -277,12 +277,12 @@ export const appRouter = router({ projects: router({ create: protectedProcedure + .input(z.object({ name: z.string(), orgId: z.string() })) .use(requireRole(["OWNER", "ADMIN"])) - .input(z.object({ name: z.string(), organizationId: z.string() })) .mutation(async ({ input, ctx }) => { const session = ctx.session as Session; const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, include: { subscription: true, projects: true, @@ -314,7 +314,8 @@ export const appRouter = router({ // Create project first with PENDING status const project = await prisma.project.create({ data: { - ...input, + name: input.name, + orgId: input.orgId, status: "PENDING", statusMessage: "Project created, initializing tenant deployment", metadata: { @@ -332,7 +333,7 @@ export const appRouter = router({ schema_name: project.id, admin_email: session.user.email, domain: `${project.id}.${TENANT_API_DOMAIN!.split(":")[0]}`, - app_domains: [`http://${project.id}.${TENANT_DASHBOARD_DOMAIN}`], + app_domains: [`${project.id}.${TENANT_DASHBOARD_DOMAIN}`], }, }, "Failed to create tenant", @@ -376,12 +377,12 @@ export const appRouter = router({ }), get: protectedProcedure - .input(z.object({ id: z.string(), organizationId: z.string() })) + .input(z.object({ id: z.string(), orgId: z.string() })) .query(async ({ input }) => { const project = await prisma.project.findFirst({ where: { id: input.id, - organizationId: input.organizationId, + orgId: input.orgId, }, }); @@ -400,9 +401,10 @@ export const appRouter = router({ z.object({ id: z.string(), name: z.string(), - organizationId: z.string(), + orgId: z.string(), }), ) + .use(requireRole(["OWNER", "ADMIN"])) .mutation(async ({ input }) => { return prisma.project.update({ where: { id: input.id }, @@ -411,10 +413,10 @@ export const appRouter = router({ }), getAll: protectedProcedure - .input(z.object({ organizationId: z.string() })) + .input(z.object({ orgId: z.string() })) .query(async ({ input }) => { const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, include: { subscription: true, projects: true, @@ -444,8 +446,8 @@ export const appRouter = router({ }), delete: protectedProcedure - .use(requireRole(["OWNER", "ADMIN"])) .input(z.object({ id: z.string() })) + .use(requireRole(["OWNER", "ADMIN"])) .mutation(async ({ input }) => { const project = await prisma.project.findUnique({ where: { id: input.id }, @@ -743,57 +745,102 @@ export const appRouter = router({ checkTenantHealth: protectedProcedure .input(z.object({ projectId: z.string() })) .mutation(async ({ input }) => { + return prisma.project.update({ + where: { id: input.projectId }, + data: { + status: "PENDING", + statusMessage: "Checking tenant health...", + }, + }); + }), + + retryDeployment: protectedProcedure + .input(z.object({ projectId: z.string() })) + .mutation(async ({ input, ctx }) => { + const session = ctx.session as Session; const project = await prisma.project.findUnique({ where: { id: input.projectId }, }); - if (!project?.tenantId) { + if (!project) { throw new TRPCError({ code: "NOT_FOUND", - message: "Project tenant not deployed", + message: "Project not found", }); } - try { - const response = await karrio( - gqlstr(GET_TENANT), - { id: project.tenantId }, - "Failed to fetch tenant details", - ); + // Update project status to pending + await prisma.project.update({ + where: { id: input.projectId }, + data: { + status: "PENDING", + statusMessage: "Retrying deployment...", + metadata: { + ...(project.metadata as Record), + deployment_retry_at: new Date().toISOString(), + }, + }, + }); - if (response?.tenant) { + // Dispatch tenant creation asynchronously + karrio( + gqlstr(CREATE_TENANT), + { + input: { + name: project.name, + schema_name: project.id, + admin_email: session.user.email, + domain: `${project.id}.${TENANT_API_DOMAIN!.split(":")[0]}`, + app_domains: [`${project.id}.${TENANT_DASHBOARD_DOMAIN}`], + }, + }, + "Failed to create tenant", + ) + .then(async (response) => { + if (response?.create_tenant?.tenant) { + await prisma.project.update({ + where: { id: project.id }, + data: { + tenantId: response.create_tenant.tenant.id, + status: "ACTIVE", + statusMessage: "Tenant deployed successfully", + metadata: { + ...(project.metadata as Record), + deployment_completed_at: new Date().toISOString(), + tenant_created_at: new Date().toISOString(), + }, + }, + }); + } else { + throw new Error("Tenant creation response is invalid"); + } + }) + .catch(async (error) => { + console.error("Failed to create tenant:", error.data || error); await prisma.project.update({ where: { id: project.id }, data: { - status: "ACTIVE", - lastPing: new Date(), - statusMessage: "Tenant is healthy", + status: "FAILED", + statusMessage: `Tenant deployment failed: ${error.message}`, + metadata: { + ...(project.metadata as Record), + deployment_failed_at: new Date().toISOString(), + error_details: error.data || error.message, + }, }, }); - return { status: "healthy" }; - } - } catch (error) { - await prisma.project.update({ - where: { id: project.id }, - data: { - status: "UNREACHABLE", - statusMessage: "Tenant is not responding", - }, - }); - throw new TRPCError({ - code: "INTERNAL_SERVER_ERROR", - message: "Tenant is unreachable", }); - } + + return project; }), }), billing: router({ getSubscription: protectedProcedure - .input(z.object({ organizationId: z.string() })) + .input(z.object({ orgId: z.string() })) .query(async ({ input }): Promise => { const subscription = await prisma.subscription.findUnique({ - where: { organizationId: input.organizationId }, + where: { orgId: input.orgId }, include: { organization: true, }, @@ -847,13 +894,13 @@ export const appRouter = router({ createCheckoutSession: protectedProcedure .input( z.object({ - organizationId: z.string(), + orgId: z.string(), priceId: z.string(), }), ) .mutation(async ({ input }) => { const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, }); if (!org?.stripeCustomerId) { @@ -873,18 +920,18 @@ export const appRouter = router({ quantity: 1, }, ], - success_url: `${process.env.NEXTAUTH_URL}/orgs/${input.organizationId}/billing?success=true`, - cancel_url: `${process.env.NEXTAUTH_URL}/orgs/${input.organizationId}/billing?canceled=true`, + success_url: `${process.env.NEXTAUTH_URL}/orgs/${input.orgId}/billing?success=true`, + cancel_url: `${process.env.NEXTAUTH_URL}/orgs/${input.orgId}/billing?canceled=true`, }); return { url: session.url }; }), getPlan: protectedProcedure - .input(z.object({ organizationId: z.string() })) + .input(z.object({ orgId: z.string() })) .query(async ({ input }) => { const subscription = await prisma.subscription.findUnique({ - where: { organizationId: input.organizationId }, + where: { orgId: input.orgId }, }); if (subscription?.stripePriceId) { @@ -940,7 +987,7 @@ export const appRouter = router({ interval: interval, features: PRODUCT_FEATURES[ - product.metadata.tier as keyof typeof PRODUCT_FEATURES + product.metadata.tier as keyof typeof PRODUCT_FEATURES ] || [], description: product.description, maxProjects: parseInt(product.metadata.max_projects || "0"), @@ -970,10 +1017,10 @@ export const appRouter = router({ }), getInvoices: protectedProcedure - .input(z.object({ organizationId: z.string() })) + .input(z.object({ orgId: z.string() })) .query(async ({ input }) => { const subscription = await prisma.subscription.findUnique({ - where: { organizationId: input.organizationId }, + where: { orgId: input.orgId }, include: { organization: true }, }); @@ -988,10 +1035,10 @@ export const appRouter = router({ }), createPortalSession: protectedProcedure - .input(z.object({ organizationId: z.string() })) + .input(z.object({ orgId: z.string() })) .mutation(async ({ input }) => { const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, }); if (!org?.stripeCustomerId) { @@ -1003,17 +1050,17 @@ export const appRouter = router({ const session = await stripe.billingPortal.sessions.create({ customer: org.stripeCustomerId, - return_url: `${process.env.NEXTAUTH_URL}/orgs/${input.organizationId}/billing`, + return_url: `${process.env.NEXTAUTH_URL}/orgs/${input.orgId}/billing`, }); return { url: session.url }; }), getBillingInfo: protectedProcedure - .input(z.object({ organizationId: z.string() })) + .input(z.object({ orgId: z.string() })) .query(async ({ input }) => { const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, }); if (!org?.stripeCustomerId) { @@ -1039,13 +1086,13 @@ export const appRouter = router({ updatePaymentMethod: protectedProcedure .input( z.object({ - organizationId: z.string(), + orgId: z.string(), paymentMethodId: z.string(), }), ) .mutation(async ({ input }) => { const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, }); if (!org?.stripeCustomerId) { @@ -1067,7 +1114,7 @@ export const appRouter = router({ updateBillingInfo: protectedProcedure .input( z.object({ - organizationId: z.string(), + orgId: z.string(), email: z.string().email().optional(), address: z .object({ @@ -1089,7 +1136,7 @@ export const appRouter = router({ ) .mutation(async ({ input }) => { const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, }); if (!org?.stripeCustomerId) { @@ -1120,10 +1167,10 @@ export const appRouter = router({ }), createSetupIntent: protectedProcedure - .input(z.object({ organizationId: z.string() })) + .input(z.object({ orgId: z.string() })) .mutation(async ({ input }) => { const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, }); if (!org?.stripeCustomerId) { @@ -1144,10 +1191,10 @@ export const appRouter = router({ }), getPaymentMethods: protectedProcedure - .input(z.object({ organizationId: z.string() })) + .input(z.object({ orgId: z.string() })) .query(async ({ input }) => { const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, }); if (!org?.stripeCustomerId) { @@ -1168,13 +1215,13 @@ export const appRouter = router({ setDefaultPaymentMethod: protectedProcedure .input( z.object({ - organizationId: z.string(), + orgId: z.string(), paymentMethodId: z.string(), }), ) .mutation(async ({ input }) => { const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, }); if (!org?.stripeCustomerId) { @@ -1197,13 +1244,13 @@ export const appRouter = router({ deletePaymentMethod: protectedProcedure .input( z.object({ - organizationId: z.string(), + orgId: z.string(), paymentMethodId: z.string(), }), ) .mutation(async ({ input }) => { const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, }); if (!org?.stripeCustomerId) { @@ -1222,13 +1269,13 @@ export const appRouter = router({ createSubscription: protectedProcedure .input( z.object({ - organizationId: z.string(), + orgId: z.string(), priceId: z.string(), }), ) .mutation(async ({ input }) => { const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, include: { subscription: true, }, @@ -1308,10 +1355,10 @@ export const appRouter = router({ // Update subscription in database await prisma.subscription.upsert({ where: { - organizationId: input.organizationId, + orgId: input.orgId, }, create: { - organizationId: input.organizationId, + orgId: input.orgId, stripeSubscriptionId: subscription.id, stripePriceId: input.priceId, status: subscription.status, @@ -1339,10 +1386,10 @@ export const appRouter = router({ }), cancelSubscription: protectedProcedure - .input(z.object({ organizationId: z.string() })) + .input(z.object({ orgId: z.string() })) .mutation(async ({ input }) => { const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, include: { subscription: true }, }); @@ -1364,7 +1411,7 @@ export const appRouter = router({ // Update subscription in database await prisma.subscription.update({ - where: { organizationId: input.organizationId }, + where: { orgId: input.orgId }, data: { status: "canceling", }, @@ -1380,10 +1427,10 @@ export const appRouter = router({ }), reactivateSubscription: protectedProcedure - .input(z.object({ organizationId: z.string() })) + .input(z.object({ orgId: z.string() })) .mutation(async ({ input }) => { const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, include: { subscription: true }, }); @@ -1405,7 +1452,7 @@ export const appRouter = router({ // Update subscription in database await prisma.subscription.update({ - where: { organizationId: input.organizationId }, + where: { orgId: input.orgId }, data: { status: "active", }, @@ -1421,10 +1468,10 @@ export const appRouter = router({ }), deleteOrganization: protectedProcedure - .input(z.object({ organizationId: z.string() })) + .input(z.object({ orgId: z.string() })) .mutation(async ({ input }) => { const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, include: { subscription: true, members: true, @@ -1455,15 +1502,15 @@ export const appRouter = router({ await prisma.$transaction([ // Delete subscription prisma.subscription.deleteMany({ - where: { organizationId: input.organizationId }, + where: { orgId: input.orgId }, }), // Delete members prisma.organizationMembership.deleteMany({ - where: { organizationId: input.organizationId }, + where: { orgId: input.orgId }, }), // Delete organization prisma.organization.delete({ - where: { id: input.organizationId }, + where: { id: input.orgId }, }), ]); @@ -1479,13 +1526,13 @@ export const appRouter = router({ retrySubscriptionPayment: protectedProcedure .input( z.object({ - organizationId: z.string(), + orgId: z.string(), paymentMethodId: z.string(), }), ) .mutation(async ({ input }) => { const org = await prisma.organization.findUnique({ - where: { id: input.organizationId }, + where: { id: input.orgId }, include: { subscription: true }, }); @@ -1520,7 +1567,7 @@ export const appRouter = router({ // Update subscription status in database await prisma.subscription.update({ - where: { organizationId: input.organizationId }, + where: { orgId: input.orgId }, data: { status: "active", }, diff --git a/ee/packages/console/types/index.ts b/ee/packages/console/types/index.ts index 79424c984..ad5bb6df0 100644 --- a/ee/packages/console/types/index.ts +++ b/ee/packages/console/types/index.ts @@ -3,16 +3,16 @@ export * from "@karrio/console/types/api"; export interface Project { id: string; name: string; - organizationId: string; + orgId: string; tenantId: string | null; tenantApiKey: string | null; status: - | "PENDING" - | "DEPLOYING" - | "ACTIVE" - | "FAILED" - | "UNREACHABLE" - | "DELETED"; + | "PENDING" + | "DEPLOYING" + | "ACTIVE" + | "FAILED" + | "UNREACHABLE" + | "DELETED"; statusMessage: string | null; metadata: { deployment_started_at: string; diff --git a/modules/core/karrio/server/core/dataunits.py b/modules/core/karrio/server/core/dataunits.py index 1673ae015..2f8136486 100644 --- a/modules/core/karrio/server/core/dataunits.py +++ b/modules/core/karrio/server/core/dataunits.py @@ -1,4 +1,5 @@ import typing +from constance import config from django.urls import reverse from rest_framework.request import Request @@ -44,11 +45,21 @@ def contextual_metadata(request: Request): ), ) host = _host[:-1] if _host[-1] == "/" else _host + name = lib.identity( + getattr(conf.settings.tenant, "name", conf.settings.APP_NAME) + if conf.settings.MULTI_TENANTS + else getattr(config, "APP_NAME", None) or conf.settings.APP_NAME + ) + website = lib.identity( + getattr(conf.settings.tenant, "website", conf.settings.APP_WEBSITE) + if conf.settings.MULTI_TENANTS + else getattr(config, "APP_WEBSITE", None) or conf.settings.APP_WEBSITE + ) return { "VERSION": conf.settings.VERSION, - "APP_NAME": conf.settings.APP_NAME, - "APP_WEBSITE": conf.settings.APP_WEBSITE, + "APP_NAME": name, + "APP_WEBSITE": website, "HOST": f"{host}/", "ADMIN": f"{host}/admin", "GRAPHQL": f"{host}/graphql", diff --git a/modules/graph/karrio/server/graph/schemas/base/inputs.py b/modules/graph/karrio/server/graph/schemas/base/inputs.py index 725a868c8..29091328d 100644 --- a/modules/graph/karrio/server/graph/schemas/base/inputs.py +++ b/modules/graph/karrio/server/graph/schemas/base/inputs.py @@ -78,7 +78,7 @@ class AddressFilter(TemplateFilter): @strawberry.input -class CarrierFilter(utils.BaseInput): +class CarrierFilter(utils.Paginated): active: typing.Optional[bool] = strawberry.UNSET metadata_key: typing.Optional[str] = strawberry.UNSET metadata_value: typing.Optional[str] = strawberry.UNSET diff --git a/packages/admin/components/admin-sidebar.tsx b/packages/admin/components/admin-sidebar.tsx index c4b622025..e5be320fb 100644 --- a/packages/admin/components/admin-sidebar.tsx +++ b/packages/admin/components/admin-sidebar.tsx @@ -15,32 +15,33 @@ import { usePathname } from "next/navigation"; const menuItems = [ { - label: "Platform details", + label: "Platform console", icon: LayoutDashboard, href: "/admin", }, { - label: "Carrier connections", - icon: Truck, - href: "/admin/carrier-connections", + label: "Staff and permissions", + icon: Users, + href: "/admin/staff", }, { - label: "Users and permissions", - icon: Users, - href: "/admin/users-permissions", + label: "Carriers network", + icon: Truck, + href: "/admin/carriers", }, { - label: "Organization accounts", + label: "Connected accounts", icon: Building2, - href: "/admin/organization-accounts", + href: "/admin/accounts", }, { - label: "Surcharge and discounts", + label: "Shipping add-ons", icon: FileText, - href: "/admin/surcharges", + href: "/admin/addons", + isDisabled: true, }, { - label: "Platform activity log", + label: "Activity log", icon: Clock, href: "/admin/activity", isDisabled: true, diff --git a/packages/admin/components/carrier-connections-table.tsx b/packages/admin/components/carrier-connections-table.tsx index b3d965210..984e55dee 100644 --- a/packages/admin/components/carrier-connections-table.tsx +++ b/packages/admin/components/carrier-connections-table.tsx @@ -8,16 +8,17 @@ import { TableRow, } from "@karrio/insiders/components/ui/table"; import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from "@karrio/insiders/components/ui/dropdown-menu"; + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@karrio/insiders/components/ui/select"; import { CarrierImage } from "@karrio/ui/components/carrier-image"; import { Button } from "@karrio/insiders/components/ui/button"; import { Switch } from "@karrio/insiders/components/ui/switch"; import { Badge } from "@karrio/insiders/components/ui/badge"; -import { MoreVertical, Copy, ChevronLeft, ChevronRight } from "lucide-react"; +import { Copy, ChevronLeft, ChevronRight, Pencil, Trash2 } from "lucide-react"; import { isNoneOrEmpty } from "@karrio/lib"; export type Connection = GetSystemConnections_system_carrier_connections_edges_node & { @@ -38,8 +39,10 @@ interface CarrierConnectionsTableProps { count: number; hasNext: boolean; page: number; + pageSize?: number; }; onPageChange?: (page: number) => void; + onPageSizeChange?: (pageSize: number) => void; } export function CarrierConnectionsTable({ @@ -52,7 +55,14 @@ export function CarrierConnectionsTable({ onCreateNew, pagination, onPageChange, + onPageSizeChange, }: CarrierConnectionsTableProps) { + // Calculate start and end indices for current page + const pageSize = pagination?.pageSize || 10; + const startIndex = pagination ? (pagination.page - 1) * pageSize : 0; + const endIndex = pagination ? startIndex + pageSize : connections.length; + const currentPageConnections = pagination ? connections.slice(startIndex, endIndex) : connections; + if (connections.length === 0) { return (
@@ -92,15 +102,17 @@ export function CarrierConnectionsTable({ - {connections?.map((connection) => ( + {currentPageConnections?.map((connection) => (
- +
+ +
{connection.carrier_id} @@ -134,7 +146,7 @@ export function CarrierConnectionsTable({ {capability} @@ -148,24 +160,24 @@ export function CarrierConnectionsTable({ /> - - - - - - onEdit(connection)}> - Edit - - onDelete(connection)} - className="text-red-600" - > - Delete - - - +
+ + +
))} @@ -173,9 +185,29 @@ export function CarrierConnectionsTable({ {pagination && (
-

- Showing {connections.length} of {pagination.count} connections -

+
+

+ Showing {startIndex + 1} to {Math.min(endIndex, connections.length)} of {connections.length} connections +

+
+ Items per page: + +
+
); } return ( - - - {rateSheets?.map(({ node: sheet }) => ( - - -
-
-
{sheet.name}
-
- {sheet.id} - +
+
+ +
+ +
+ + {rateSheets?.map(({ node: sheet }) => ( + + +
+
+
{sheet.name}
+
+ {sheet.carrier_name} +
- -
- -
- - {sheet.carrier_name} -
-
- -
- {!isNoneOrEmpty(sheet.services) && - sheet.services?.map((service) => ( - - {service.service_code} + + +
+ {sheet.services?.map((service) => ( + + {service.service_name} ))} -
-
- - - - - - - onEdit(sheet)}> - Edit - - onDelete(sheet)} - className="text-red-600" - > - Delete - - - - - - ))} - -
+
+ + + + + + + + onEdit(sheet)}> + Edit + + onDelete(sheet)}> + Delete + + + onCopy(sheet.id, "Rate sheet ID copied to clipboard") + } + > + + Copy ID + + + + + + ))} + + +
); } diff --git a/packages/admin/modules/organization-accounts/index.tsx b/packages/admin/modules/accounts/index.tsx similarity index 100% rename from packages/admin/modules/organization-accounts/index.tsx rename to packages/admin/modules/accounts/index.tsx diff --git a/packages/admin/modules/surcharges/index.tsx b/packages/admin/modules/addons/index.tsx similarity index 100% rename from packages/admin/modules/surcharges/index.tsx rename to packages/admin/modules/addons/index.tsx diff --git a/packages/admin/modules/carrier-connections/index.tsx b/packages/admin/modules/carrier-connections/index.tsx deleted file mode 100644 index e8c798dbe..000000000 --- a/packages/admin/modules/carrier-connections/index.tsx +++ /dev/null @@ -1,307 +0,0 @@ -"use client"; - -import { CarrierConnectionsTable, Connection } from "@karrio/admin/components/carrier-connections-table"; -import { GetRateSheets_rate_sheets_edges_node as RateSheet } from "@karrio/types/graphql/admin/types"; -import { DeleteConfirmationDialog } from "@karrio/insiders/components/delete-confirmation-dialog"; -import { CarrierConnectionDialog } from "@karrio/insiders/components/carrier-connection-dialog"; -import { Card, CardContent, CardHeader, CardTitle } from "@karrio/insiders/components/ui/card"; -import { RateSheetDialog } from "@karrio/insiders/components/rate-sheet-dialog"; -import { RateSheetsTable } from "@karrio/admin/components/rate-sheets-table"; -import { Button } from "@karrio/insiders/components/ui/button"; -import { useToast } from "@karrio/insiders/hooks/use-toast"; -import { trpc } from "@karrio/trpc/client"; -import { useState } from "react"; - -export default function CarrierConnections() { - const utils = trpc.useContext(); - const { toast } = useToast(); - const [isEditOpen, setIsEditOpen] = useState(false); - const [isDeleteOpen, setIsDeleteOpen] = useState(false); - const [selectedConnection, setSelectedConnection] = useState(null); - const [page, setPage] = useState(1); - - const { data: connections, isLoading } = trpc.admin.system_connections.list.useQuery({ - filter: {}, - }); - - const updateConnection = trpc.admin.system_connections.update.useMutation({ - onSuccess: () => { - toast({ title: "Carrier connection updated successfully" }); - setIsEditOpen(false); - setSelectedConnection(null); - utils.admin.system_connections.list.invalidate(); - }, - onError: (error) => { - toast({ - title: "Failed to update carrier connection", - description: error.message, - variant: "destructive", - }); - }, - }); - - const deleteConnection = trpc.admin.system_connections.delete.useMutation({ - onSuccess: () => { - toast({ title: "Carrier connection deleted successfully" }); - setIsDeleteOpen(false); - setSelectedConnection(null); - utils.admin.system_connections.list.invalidate(); - }, - onError: (error) => { - toast({ - title: "Failed to delete carrier connection", - description: error.message, - variant: "destructive", - }); - }, - }); - - const handleUpdate = (values: any) => { - updateConnection.mutate({ - data: { - id: values.id, - carrier_name: values.carrier_name, - display_name: values.display_name, - test_mode: values.test_mode, - active: values.active, - capabilities: values.capabilities, - credentials: values.credentials || {}, - config: values.config || {}, - }, - }); - }; - - const handleCopy = async (text: string, description: string) => { - try { - await navigator.clipboard.writeText(text); - toast({ - title: "Copied to clipboard", - description, - }); - } catch (error) { - toast({ - title: "Failed to copy to clipboard", - description: "Please copy the text manually", - variant: "destructive", - }); - } - }; - - return ( -
-
-

- Carrier Management -

-
- -
- - - System Carrier Connections -

- Manage system-wide carrier connections that are available to all organizations. -

-
- - setIsEditOpen(true)} - connections={connections?.edges?.map(edge => ({ - ...edge.node, - credentials: edge.node.credentials || {}, - config: edge.node.config || {}, - metadata: edge.node.metadata || {}, - }))} - pagination={connections ? { - count: connections.edges.length, - hasNext: connections.page_info.has_next_page, - page, - } : undefined} - onPageChange={setPage} - onEdit={(connection) => { - setSelectedConnection(connection); - setIsEditOpen(true); - }} - onDelete={(connection) => { - setSelectedConnection(connection); - setIsDeleteOpen(true); - }} - onStatusChange={(connection, active) => { - updateConnection.mutate({ - data: { - id: connection.id, - active, - carrier_name: connection.carrier_name, - display_name: connection.display_name || "", - test_mode: connection.test_mode, - capabilities: connection.capabilities || [], - credentials: connection.credentials || {}, - config: connection.config || {}, - metadata: connection.metadata || {}, - }, - }); - }} - onCopy={handleCopy} - /> - -
- - - - Rate Sheets -

- Manage carrier rate sheets and service configurations. -

-
- - - -
-
- - - - { - if (selectedConnection) { - deleteConnection.mutate({ - data: { - id: selectedConnection.id, - }, - }); - } - }} - /> -
- ); -} - -function RateSheets() { - const utils = trpc.useContext(); - const { toast } = useToast(); - const [isEditOpen, setIsEditOpen] = useState(false); - const [isDeleteOpen, setIsDeleteOpen] = useState(false); - const [selectedRateSheet, setSelectedRateSheet] = useState(null); - - const { data: rateSheets, isLoading } = trpc.admin.rate_sheets.list.useQuery({ - filter: {}, - }); - - const updateRateSheet = trpc.admin.rate_sheets.update.useMutation({ - onSuccess: () => { - toast({ title: "Rate sheet updated successfully" }); - setIsEditOpen(false); - setSelectedRateSheet(null); - utils.admin.rate_sheets.list.invalidate(); - }, - onError: (error) => { - toast({ - title: "Failed to update rate sheet", - description: error.message, - variant: "destructive", - }); - }, - }); - - const deleteRateSheet = trpc.admin.rate_sheets.delete.useMutation({ - onSuccess: () => { - toast({ title: "Rate sheet deleted successfully" }); - setIsDeleteOpen(false); - setSelectedRateSheet(null); - utils.admin.rate_sheets.list.invalidate(); - }, - onError: (error) => { - toast({ - title: "Failed to delete rate sheet", - description: error.message, - variant: "destructive", - }); - }, - }); - - const handleUpdate = async (values: any) => { - return updateRateSheet.mutateAsync({ - data: { - id: values.id, - name: values.name, - carrier_name: values.carrier_name, - services: values.services, - }, - }); - }; - - const handleCopy = async (text: string, description: string) => { - try { - await navigator.clipboard.writeText(text); - toast({ - title: "Copied to clipboard", - description, - }); - } catch (error) { - toast({ - title: "Failed to copy to clipboard", - description: "Please copy the text manually", - variant: "destructive", - }); - } - }; - - return ( -
-
- -
- - { - const rateSheetWithMetadata = { - ...sheet, - metadata: sheet.metadata || {}, - }; - setSelectedRateSheet(rateSheetWithMetadata); - setIsEditOpen(true); - }} - onDelete={(sheet) => { - const rateSheetWithMetadata = { - ...sheet, - metadata: sheet.metadata || {}, - }; - setSelectedRateSheet(rateSheetWithMetadata); - setIsDeleteOpen(true); - }} - onCopy={handleCopy} - /> - - - - { - if (selectedRateSheet) { - deleteRateSheet.mutate({ - data: { id: selectedRateSheet.id }, - }); - } - }} - /> -
- ); -} diff --git a/packages/admin/modules/carriers/index.tsx b/packages/admin/modules/carriers/index.tsx new file mode 100644 index 000000000..533023278 --- /dev/null +++ b/packages/admin/modules/carriers/index.tsx @@ -0,0 +1,539 @@ +"use client"; + +import { CarrierConnectionsTable, Connection } from "@karrio/admin/components/carrier-connections-table"; +import { GetRateSheets_rate_sheets_edges_node as RateSheet } from "@karrio/types/graphql/admin/types"; +import { DeleteConfirmationDialog } from "@karrio/insiders/components/delete-confirmation-dialog"; +import { CarrierConnectionDialog } from "@karrio/insiders/components/carrier-connection-dialog"; +import { Card, CardContent, CardHeader, CardTitle } from "@karrio/insiders/components/ui/card"; +import { RateSheetDialog } from "@karrio/insiders/components/rate-sheet-dialog"; +import { RateSheetsTable } from "@karrio/admin/components/rate-sheets-table"; +import { CarrierNameEnum } from "@karrio/types/graphql/admin/types"; +import { Button } from "@karrio/insiders/components/ui/button"; +import { Input } from "@karrio/insiders/components/ui/input"; +import { useToast } from "@karrio/insiders/hooks/use-toast"; +import { Plus, Search, X, Filter } from "lucide-react"; +import { trpc } from "@karrio/trpc/client"; +import { Loader2 } from "lucide-react"; +import { useState } from "react"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, +} from "@karrio/insiders/components/ui/select"; + +export default function CarrierNetwork() { + return ( +
+
+

+ Carriers Network +

+
+ +
+ + {/* */} +
+
+ ); +} + +function CarrierConnectionManagement() { + const utils = trpc.useContext(); + const { toast } = useToast(); + const [isEditOpen, setIsEditOpen] = useState(false); + const [isDeleteOpen, setIsDeleteOpen] = useState(false); + const [selectedConnection, setSelectedConnection] = useState(null); + const [page, setPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + const [filters, setFilters] = useState({ + active: undefined as boolean | undefined, + search: "" as string, + carrier_name: [] as string[], + }); + + const { data: connections, isLoading } = trpc.admin.system_connections.list.useQuery({ + filter: { + offset: (page - 1) * pageSize, + first: pageSize, + active: filters.active, + carrier_name: filters.carrier_name.length > 0 ? filters.carrier_name : undefined, + metadata_key: filters.search || undefined, + metadata_value: filters.search || undefined, + }, + }); + + const createConnection = trpc.admin.system_connections.create.useMutation({ + onSuccess: () => { + toast({ title: "Carrier connection created successfully" }); + setIsEditOpen(false); + setSelectedConnection(null); + utils.admin.system_connections.list.invalidate(); + }, + onError: (error) => { + toast({ + title: "Failed to create carrier connection", + description: error.message, + variant: "destructive", + }); + }, + }); + + const updateConnection = trpc.admin.system_connections.update.useMutation({ + onSuccess: () => { + toast({ title: "Carrier connection updated successfully" }); + setIsEditOpen(false); + setSelectedConnection(null); + utils.admin.system_connections.list.invalidate(); + }, + onError: (error) => { + toast({ + title: "Failed to update carrier connection", + description: error.message, + variant: "destructive", + }); + }, + }); + + const deleteConnection = trpc.admin.system_connections.delete.useMutation({ + onSuccess: () => { + toast({ title: "Carrier connection deleted successfully" }); + setIsDeleteOpen(false); + setSelectedConnection(null); + utils.admin.system_connections.list.invalidate(); + }, + onError: (error) => { + toast({ + title: "Failed to delete carrier connection", + description: error.message, + variant: "destructive", + }); + }, + }); + + const handleUpdate = (values: any) => { + // Convert empty strings to undefined in credentials + const credentials = Object.entries(values.credentials || {}).reduce((acc, [key, value]) => ({ + ...acc, + [key]: value === "" ? undefined : value, + }), {}); + + // Convert empty strings to undefined in config + const config = Object.entries(values.config || {}).reduce((acc, [key, value]) => ({ + ...acc, + [key]: value === "" ? undefined : value, + }), {}); + + // Convert empty strings to undefined in metadata + const metadata = Object.entries(values.metadata || {}).reduce((acc, [key, value]) => ({ + ...acc, + [key]: value === "" ? undefined : value, + }), {}); + + if (selectedConnection) { + // Update existing connection + updateConnection.mutate({ + data: { + id: selectedConnection.id, + carrier_id: values.carrier_id === "" ? undefined : values.carrier_id, + active: values.active, + capabilities: values.capabilities, + credentials, + config, + metadata, + }, + }); + } else { + // Create new connection + createConnection.mutate({ + data: { + carrier_name: values.carrier_name, + carrier_id: values.carrier_id === "" ? undefined : values.carrier_id, + active: values.active, + capabilities: values.capabilities, + credentials, + config, + metadata, + }, + }); + } + }; + + const handleCopy = async (text: string, description: string) => { + try { + await navigator.clipboard.writeText(text); + toast({ + title: "Copied to clipboard", + description, + }); + } catch (error) { + toast({ + title: "Failed to copy to clipboard", + description: "Please copy the text manually", + variant: "destructive", + }); + } + }; + + // Reset page when filters change + const handleFilterChange = (newFilters: typeof filters) => { + setPage(1); + setFilters(newFilters); + }; + + return ( + + +
+
+ System Carrier Connections +

+ Manage system-wide carrier connections that are available to all organizations. +

+
+ +
+
+ +
+
+ + handleFilterChange({ + ...filters, + search: e.target.value, + })} + className="pl-8 pr-8" + /> + {filters.search && ( + + )} +
+ + + + + + {(filters.active !== undefined || filters.carrier_name.length > 0) && ( + + )} +
+ + {isLoading ? ( +
+ +
+ ) : ( + { + setSelectedConnection(null); + setIsEditOpen(true); + }} + connections={connections?.edges?.map(edge => ({ + ...edge.node, + credentials: edge.node.credentials || {}, + config: edge.node.config || {}, + metadata: edge.node.metadata || {}, + }))} + pagination={connections ? { + count: connections.edges.length + ((page - 1) * pageSize), + hasNext: connections.page_info.has_next_page, + page, + pageSize, + } : undefined} + onPageChange={setPage} + onPageSizeChange={setPageSize} + onEdit={(connection) => { + setSelectedConnection(connection); + setIsEditOpen(true); + }} + onDelete={(connection) => { + setSelectedConnection(connection); + setIsDeleteOpen(true); + }} + onStatusChange={(connection, active) => { + updateConnection.mutate({ + data: { + id: connection.id, + active, + }, + }); + }} + onCopy={handleCopy} + /> + )} + + + + { + if (selectedConnection) { + deleteConnection.mutate({ + data: { + id: selectedConnection.id, + }, + }); + } + }} + /> +
+
+ ); +} + +function RateSheetManagement() { + const utils = trpc.useContext(); + const { toast } = useToast(); + const [isEditOpen, setIsEditOpen] = useState(false); + const [isDeleteOpen, setIsDeleteOpen] = useState(false); + const [selectedRateSheet, setSelectedRateSheet] = useState(null); + + const { data: rateSheets, isLoading } = trpc.admin.rate_sheets.list.useQuery({ + filter: {}, + }); + + const createRateSheet = trpc.admin.rate_sheets.create.useMutation({ + onSuccess: () => { + toast({ title: "Rate sheet created successfully" }); + setIsEditOpen(false); + setSelectedRateSheet(null); + utils.admin.rate_sheets.list.invalidate(); + }, + onError: (error) => { + toast({ + title: "Failed to create rate sheet", + description: error.message, + variant: "destructive", + }); + }, + }); + + const updateRateSheet = trpc.admin.rate_sheets.update.useMutation({ + onSuccess: () => { + toast({ title: "Rate sheet updated successfully" }); + setIsEditOpen(false); + setSelectedRateSheet(null); + utils.admin.rate_sheets.list.invalidate(); + }, + onError: (error) => { + toast({ + title: "Failed to update rate sheet", + description: error.message, + variant: "destructive", + }); + }, + }); + + const deleteRateSheet = trpc.admin.rate_sheets.delete.useMutation({ + onSuccess: () => { + toast({ title: "Rate sheet deleted successfully" }); + setIsDeleteOpen(false); + setSelectedRateSheet(null); + utils.admin.rate_sheets.list.invalidate(); + }, + onError: (error) => { + toast({ + title: "Failed to delete rate sheet", + description: error.message, + variant: "destructive", + }); + }, + }); + + const handleUpdate = async (values: any) => { + if (selectedRateSheet) { + return updateRateSheet.mutateAsync({ + data: { + id: values.id, + name: values.name, + carrier_name: values.carrier_name, + services: values.services, + }, + }); + } else { + return createRateSheet.mutateAsync({ + data: { + name: values.name, + carrier_name: values.carrier_name, + services: values.services, + }, + }); + } + }; + + const handleCopy = async (text: string, description: string) => { + try { + await navigator.clipboard.writeText(text); + toast({ + title: "Copied to clipboard", + description, + }); + } catch (error) { + toast({ + title: "Failed to copy to clipboard", + description: "Please copy the text manually", + variant: "destructive", + }); + } + }; + + return ( + + +
+
+ Rate Sheets +

+ Manage carrier rate sheets and service configurations. +

+
+ +
+
+ + {isLoading ? ( +
+ +
+ ) : ( + { + setSelectedRateSheet(null); + setIsEditOpen(true); + }} + onEdit={(sheet) => { + const rateSheetWithMetadata = { + ...sheet, + metadata: sheet.metadata || {}, + }; + setSelectedRateSheet(rateSheetWithMetadata); + setIsEditOpen(true); + }} + onDelete={(sheet) => { + const rateSheetWithMetadata = { + ...sheet, + metadata: sheet.metadata || {}, + }; + setSelectedRateSheet(rateSheetWithMetadata); + setIsDeleteOpen(true); + }} + onCopy={handleCopy} + /> + )} + + + + { + if (selectedRateSheet) { + deleteRateSheet.mutate({ + data: { id: selectedRateSheet.id }, + }); + } + }} + /> +
+
+ ); +} diff --git a/packages/admin/modules/platform-details/index.tsx b/packages/admin/modules/platform-details/index.tsx deleted file mode 100644 index d6cf88019..000000000 --- a/packages/admin/modules/platform-details/index.tsx +++ /dev/null @@ -1,539 +0,0 @@ -"use client"; - -import { - Card, - CardContent, - CardHeader, - CardTitle, -} from "@karrio/insiders/components/ui/card"; -import { Switch } from "@karrio/insiders/components/ui/switch"; -import { Input } from "@karrio/insiders/components/ui/input"; -import { Button } from "@karrio/insiders/components/ui/button"; -import { Label } from "@karrio/insiders/components/ui/label"; -import { useToast } from "@karrio/insiders/hooks/use-toast"; -import { useAPIMetadata } from "@karrio/hooks/api-metadata"; -import { trpc } from "@karrio/trpc/client"; -import { useState } from "react"; -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, -} from "@karrio/insiders/components/ui/dialog"; - -type ConfigData = { - EMAIL_USE_TLS: boolean; - EMAIL_HOST_USER: string; - EMAIL_HOST_PASSWORD: string; - EMAIL_HOST: string; - EMAIL_PORT: number; - EMAIL_FROM_ADDRESS: string; - GOOGLE_CLOUD_API_KEY: string; - CANADAPOST_ADDRESS_COMPLETE_API_KEY: string; - ORDER_DATA_RETENTION: number; - TRACKER_DATA_RETENTION: number; - SHIPMENT_DATA_RETENTION: number; - API_LOGS_DATA_RETENTION: number; - APP_NAME: string; - APP_WEBSITE: string; - ALLOW_SIGNUP: boolean; - ALLOW_ADMIN_APPROVED_SIGNUP: boolean; -}; - -type ConfigResponse = { - EMAIL_USE_TLS: boolean | null; - EMAIL_HOST_USER: string | null; - EMAIL_HOST_PASSWORD: string | null; - EMAIL_HOST: string | null; - EMAIL_PORT: number | null; - EMAIL_FROM_ADDRESS: string | null; - GOOGLE_CLOUD_API_KEY: string | null; - CANADAPOST_ADDRESS_COMPLETE_API_KEY: string | null; - ORDER_DATA_RETENTION: number | null; - TRACKER_DATA_RETENTION: number | null; - SHIPMENT_DATA_RETENTION: number | null; - API_LOGS_DATA_RETENTION: number | null; - APP_NAME: string | null; - APP_WEBSITE: string | null; - ALLOW_SIGNUP: boolean | null; - ALLOW_ADMIN_APPROVED_SIGNUP: boolean | null; -}; - -const defaultConfig: ConfigData = { - EMAIL_USE_TLS: false, - EMAIL_HOST_USER: "", - EMAIL_HOST_PASSWORD: "", - EMAIL_HOST: "", - EMAIL_PORT: 587, - EMAIL_FROM_ADDRESS: "", - GOOGLE_CLOUD_API_KEY: "", - CANADAPOST_ADDRESS_COMPLETE_API_KEY: "", - ORDER_DATA_RETENTION: 90, - TRACKER_DATA_RETENTION: 90, - SHIPMENT_DATA_RETENTION: 90, - API_LOGS_DATA_RETENTION: 30, - APP_NAME: "", - APP_WEBSITE: "", - ALLOW_SIGNUP: true, - ALLOW_ADMIN_APPROVED_SIGNUP: false, -}; - -type EditSection = 'email' | 'administration' | 'data_retention' | 'api_keys' | null; - -export default function PlatformDetails() { - const { toast } = useToast(); - const { metadata } = useAPIMetadata(); - const utils = trpc.useContext(); - const { data: configs } = trpc.admin.configs.list.useQuery(); - const [editSection, setEditSection] = useState(null); - - const { mutate: updateConfigs } = trpc.admin.configs.update.useMutation({ - onSuccess: () => { - toast({ title: "Settings saved successfully" }); - utils.admin.configs.list.invalidate(); - setEditSection(null); - }, - onError: (error) => { - toast({ - title: "Failed to save settings", - description: error.message, - variant: "destructive", - }); - }, - }); - - const handleUpdate = (data: Partial) => { - updateConfigs({ data }); - }; - - const currentConfig = configs ? { - ...defaultConfig, - ...Object.fromEntries( - Object.entries(configs).map(([key, value]) => [key, value === null ? defaultConfig[key as keyof ConfigData] : value]) - ) - } as ConfigData : defaultConfig; - - return ( -
-
-

- Platform Overview -

-
- -
- {/* Platform Config */} - - - Platform Details -

- Overview of your platform configuration and API endpoints. -

-
- -
-
-
- -

{metadata?.APP_NAME}

-
-
- -

{metadata?.APP_WEBSITE}

-
-
- -

{metadata?.HOST}

-
-
- -

{metadata?.GRAPHQL}

-
-
- -

{metadata?.OPENAPI}

-
-
-
-
-
- - {/* Administration */} - - - Administration -

- Configure user access and platform behavior settings. -

-
- -
-
-
-
- -

Allow user signup

-
- -
-
-
- -

User signup requires admin approval

-
- -
-
-
-
- -
-
-
- - {/* Email Config */} - - - Email Configuration -

- Configure SMTP settings for sending system emails and notifications. -

-
- -
-
-
-
- -

{currentConfig.EMAIL_HOST || 'Not configured'}

-
-
- -

{currentConfig.EMAIL_PORT || 'Not configured'}

-
-
- -

{currentConfig.EMAIL_HOST_USER || 'Not configured'}

-
-
- -

{currentConfig.EMAIL_FROM_ADDRESS || 'Not configured'}

-
-
-
-
-
- -
-
-
- - {/* Data Retention */} - - - Data Retention -

- Set retention periods for different types of data before automatic cleanup. -

-
- -
-
-
-
- -

{currentConfig.ORDER_DATA_RETENTION || 90} days

-
-
- -

{currentConfig.SHIPMENT_DATA_RETENTION || 90} days

-
-
- -

{currentConfig.API_LOGS_DATA_RETENTION || 30} days

-
-
-
-
-
- -
-
-
- - {/* API Keys */} - - - Address Validation & Autocomplete -

- Configure third-party services for address validation and autocomplete functionality. -

-
- -
-
-
- -

- {currentConfig.GOOGLE_CLOUD_API_KEY ? '••••••••' : 'Not configured'} -

-
-
- -

- {currentConfig.CANADAPOST_ADDRESS_COMPLETE_API_KEY ? '••••••••' : 'Not configured'} -

-
-
-
-
- -
-
-
-
- - setEditSection(null)} - configs={currentConfig} - onUpdate={handleUpdate} - /> -
- ); -} - -function EditDialog({ - section, - onClose, - configs, - onUpdate -}: { - section: EditSection; - onClose: () => void; - configs: ConfigData; - onUpdate: (data: Partial) => void; -}) { - const [formData, setFormData] = useState(configs); - - const handleSubmit = (e: React.FormEvent) => { - e.preventDefault(); - const data: Partial = {}; - - switch (section) { - case 'administration': - data.ALLOW_SIGNUP = formData.ALLOW_SIGNUP; - data.ALLOW_ADMIN_APPROVED_SIGNUP = formData.ALLOW_ADMIN_APPROVED_SIGNUP; - break; - case 'email': - data.EMAIL_USE_TLS = formData.EMAIL_USE_TLS; - data.EMAIL_HOST_USER = formData.EMAIL_HOST_USER; - data.EMAIL_HOST_PASSWORD = formData.EMAIL_HOST_PASSWORD; - data.EMAIL_HOST = formData.EMAIL_HOST; - data.EMAIL_PORT = formData.EMAIL_PORT; - data.EMAIL_FROM_ADDRESS = formData.EMAIL_FROM_ADDRESS; - break; - case 'data_retention': - data.ORDER_DATA_RETENTION = formData.ORDER_DATA_RETENTION; - data.TRACKER_DATA_RETENTION = formData.TRACKER_DATA_RETENTION; - data.SHIPMENT_DATA_RETENTION = formData.SHIPMENT_DATA_RETENTION; - data.API_LOGS_DATA_RETENTION = formData.API_LOGS_DATA_RETENTION; - break; - case 'api_keys': - data.GOOGLE_CLOUD_API_KEY = formData.GOOGLE_CLOUD_API_KEY; - data.CANADAPOST_ADDRESS_COMPLETE_API_KEY = formData.CANADAPOST_ADDRESS_COMPLETE_API_KEY; - break; - } - - onUpdate(data); - }; - - const handleChange = (key: keyof ConfigData, value: any) => { - setFormData(prev => ({ ...prev, [key]: value })); - }; - - const renderContent = () => { - switch (section) { - case 'administration': - return ( -
-
-
- -

Allow user signup

-
- handleChange('ALLOW_SIGNUP', checked)} - /> -
-
-
- -

User signup requires admin approval

-
- handleChange('ALLOW_ADMIN_APPROVED_SIGNUP', checked)} - /> -
-
- ); - - case 'email': - return ( -
-
- - handleChange("EMAIL_HOST", e.target.value)} - /> -
-
- - handleChange("EMAIL_PORT", Number(e.target.value))} - /> -
-
- - handleChange("EMAIL_HOST_USER", e.target.value)} - /> -
-
- - handleChange("EMAIL_HOST_PASSWORD", e.target.value)} - /> -
-
- - handleChange("EMAIL_FROM_ADDRESS", e.target.value)} - /> -
-
- handleChange("EMAIL_USE_TLS", checked)} - /> - -
-
- ); - - case 'data_retention': - return ( -
-
- - handleChange("ORDER_DATA_RETENTION", Number(e.target.value))} - /> -
-
- - handleChange("SHIPMENT_DATA_RETENTION", Number(e.target.value))} - /> -
-
- - handleChange("API_LOGS_DATA_RETENTION", Number(e.target.value))} - /> -
-
- ); - - case 'api_keys': - return ( -
-
- - handleChange("GOOGLE_CLOUD_API_KEY", e.target.value)} - /> -
-
- - handleChange("CANADAPOST_ADDRESS_COMPLETE_API_KEY", e.target.value)} - /> -
-
- ); - - default: - return null; - } - }; - - const titles = { - administration: 'Edit Administration Settings', - email: 'Edit Email Settings', - data_retention: 'Edit Data Retention Settings', - api_keys: 'Edit API Keys', - }; - - if (!section) return null; - - return ( - onClose()}> - - - {titles[section]} - - Update your platform settings. - - -
- {renderContent()} - - - -
-
-
- ); -} diff --git a/packages/admin/modules/platform/index.tsx b/packages/admin/modules/platform/index.tsx new file mode 100644 index 000000000..c6eb2ab49 --- /dev/null +++ b/packages/admin/modules/platform/index.tsx @@ -0,0 +1,994 @@ +"use client"; + +import { + Card, + CardContent, + CardHeader, + CardTitle, +} from "@karrio/insiders/components/ui/card"; +import { Switch } from "@karrio/insiders/components/ui/switch"; +import { Input } from "@karrio/insiders/components/ui/input"; +import { Button } from "@karrio/insiders/components/ui/button"; +import { Label } from "@karrio/insiders/components/ui/label"; +import { useToast } from "@karrio/insiders/hooks/use-toast"; +import { useAPIMetadata } from "@karrio/hooks/api-metadata"; +import { trpc } from "@karrio/trpc/client"; +import { useState, useEffect } from "react"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@karrio/insiders/components/ui/dialog"; +import { Pencil, Check, X, ExternalLink, Copy } from "lucide-react"; + +type ConfigData = { + EMAIL_USE_TLS: boolean; + EMAIL_HOST_USER: string; + EMAIL_HOST_PASSWORD: string; + EMAIL_HOST: string; + EMAIL_PORT: number; + EMAIL_FROM_ADDRESS: string; + GOOGLE_CLOUD_API_KEY: string; + CANADAPOST_ADDRESS_COMPLETE_API_KEY: string; + ORDER_DATA_RETENTION: number; + TRACKER_DATA_RETENTION: number; + SHIPMENT_DATA_RETENTION: number; + API_LOGS_DATA_RETENTION: number; + APP_NAME: string; + APP_WEBSITE: string; + ALLOW_SIGNUP: boolean; + ALLOW_ADMIN_APPROVED_SIGNUP: boolean; + DOCUMENTS_MANAGEMENT: boolean; + DATA_IMPORT_EXPORT: boolean; + PERSIST_SDK_TRACING: boolean; + WORKFLOW_MANAGEMENT: boolean; + AUDIT_LOGGING: boolean; + ALLOW_MULTI_ACCOUNT: boolean; + ADMIN_DASHBOARD: boolean; + ORDERS_MANAGEMENT: boolean; + APPS_MANAGEMENT: boolean; + MULTI_ORGANIZATIONS: boolean; +}; + +type ConfigResponse = { + EMAIL_USE_TLS: boolean | null; + EMAIL_HOST_USER: string | null; + EMAIL_HOST_PASSWORD: string | null; + EMAIL_HOST: string | null; + EMAIL_PORT: number | null; + EMAIL_FROM_ADDRESS: string | null; + GOOGLE_CLOUD_API_KEY: string | null; + CANADAPOST_ADDRESS_COMPLETE_API_KEY: string | null; + ORDER_DATA_RETENTION: number | null; + TRACKER_DATA_RETENTION: number | null; + SHIPMENT_DATA_RETENTION: number | null; + API_LOGS_DATA_RETENTION: number | null; + APP_NAME: string | null; + APP_WEBSITE: string | null; + ALLOW_SIGNUP: boolean | null; + ALLOW_ADMIN_APPROVED_SIGNUP: boolean | null; + DOCUMENTS_MANAGEMENT: boolean | null; + DATA_IMPORT_EXPORT: boolean | null; + PERSIST_SDK_TRACING: boolean | null; + WORKFLOW_MANAGEMENT: boolean | null; + AUDIT_LOGGING: boolean | null; + ALLOW_MULTI_ACCOUNT: boolean | null; + ADMIN_DASHBOARD: boolean | null; + ORDERS_MANAGEMENT: boolean | null; + APPS_MANAGEMENT: boolean | null; + MULTI_ORGANIZATIONS: boolean | null; +}; + +const defaultConfig: ConfigData = { + EMAIL_USE_TLS: false, + EMAIL_HOST_USER: "", + EMAIL_HOST_PASSWORD: "", + EMAIL_HOST: "", + EMAIL_PORT: 587, + EMAIL_FROM_ADDRESS: "", + GOOGLE_CLOUD_API_KEY: "", + CANADAPOST_ADDRESS_COMPLETE_API_KEY: "", + ORDER_DATA_RETENTION: 90, + TRACKER_DATA_RETENTION: 90, + SHIPMENT_DATA_RETENTION: 90, + API_LOGS_DATA_RETENTION: 30, + APP_NAME: "", + APP_WEBSITE: "", + ALLOW_SIGNUP: true, + ALLOW_ADMIN_APPROVED_SIGNUP: false, + DOCUMENTS_MANAGEMENT: false, + DATA_IMPORT_EXPORT: false, + PERSIST_SDK_TRACING: false, + WORKFLOW_MANAGEMENT: false, + AUDIT_LOGGING: false, + ALLOW_MULTI_ACCOUNT: false, + ADMIN_DASHBOARD: false, + ORDERS_MANAGEMENT: false, + APPS_MANAGEMENT: false, + MULTI_ORGANIZATIONS: false, +}; + +type EditSection = 'email' | 'administration' | 'data_retention' | 'api_keys' | 'features' | 'platform' | null; + +export default function PlatformDetails() { + const { toast } = useToast(); + const { metadata } = useAPIMetadata(); + const utils = trpc.useContext(); + const { data: configs } = trpc.admin.configs.list.useQuery(); + const [editSection, setEditSection] = useState(null); + + const { mutate: updateConfigs } = trpc.admin.configs.update.useMutation({ + onSuccess: () => { + toast({ title: "Settings saved successfully" }); + utils.admin.configs.list.invalidate(); + setEditSection(null); + }, + onError: (error) => { + toast({ + title: "Failed to save settings", + description: error.message, + variant: "destructive", + }); + }, + }); + + const handleUpdate = (data: Partial) => { + updateConfigs({ data }); + }; + + const currentConfig = configs ? { + ...defaultConfig, + ...Object.fromEntries( + Object.entries(configs).map(([key, value]) => [key, value === null ? defaultConfig[key as keyof ConfigData] : value]) + ) + } as ConfigData : defaultConfig; + + return ( +
+
+

+ Platform Overview +

+
+ +
+ {/* Platform Config */} + + + Platform Details +

+ Overview of your platform configuration and API endpoints. +

+
+ +
+
+
+
+ +

{currentConfig.APP_NAME || metadata?.APP_NAME}

+
+ +
+
+ +
+

{currentConfig.APP_WEBSITE || metadata?.APP_WEBSITE}

+
+ + +
+
+
+
+
+
+
+
+ +
+

{metadata?.HOST}

+
+ + +
+
+
+
+ +
+

{metadata?.GRAPHQL}

+
+ + +
+
+
+
+ +
+

{metadata?.OPENAPI}

+
+ + +
+
+
+
+
+
+
+ + {/* Administration */} + + +
+ Administration +

+ Configure user access and platform behavior settings. +

+
+ +
+ +
+
+
+
+ +

Allow user signup

+
+ {currentConfig.ALLOW_SIGNUP ? ( + + ) : ( + + )} +
+
+
+ +

User signup requires admin approval

+
+ {currentConfig.ALLOW_ADMIN_APPROVED_SIGNUP ? ( + + ) : ( + + )} +
+
+
+ +

Enable audit logging for system activities

+
+ {currentConfig.AUDIT_LOGGING ? ( + + ) : ( + + )} +
+
+
+
+
+ + {/* Features */} + + +
+ Features +

+ Configure platform features and capabilities. +

+
+ +
+ +
+
+
+
+ +

Allow users to have multiple accounts

+
+ {currentConfig.ALLOW_MULTI_ACCOUNT ? ( + + ) : ( + + )} +
+
+
+ +

Enable admin dashboard access

+
+ {currentConfig.ADMIN_DASHBOARD ? ( + + ) : ( + + )} +
+
+
+ +

Enable multi-organization support

+
+ {currentConfig.MULTI_ORGANIZATIONS ? ( + + ) : ( + + )} +
+
+
+ +

Enable documents management

+
+ {currentConfig.DOCUMENTS_MANAGEMENT ? ( + + ) : ( + + )} +
+
+
+ +

Enable data import/export

+
+ {currentConfig.DATA_IMPORT_EXPORT ? ( + + ) : ( + + )} +
+
+
+ +

Persist SDK tracing

+
+ {currentConfig.PERSIST_SDK_TRACING ? ( + + ) : ( + + )} +
+
+
+ +

Enable workflow management

+
+ {currentConfig.WORKFLOW_MANAGEMENT ? ( + + ) : ( + + )} +
+
+
+ +

Enable orders management functionality

+
+ {currentConfig.ORDERS_MANAGEMENT ? ( + + ) : ( + + )} +
+
+
+ +

Enable apps management functionality

+
+ {currentConfig.APPS_MANAGEMENT ? ( + + ) : ( + + )} +
+
+
+
+
+ + {/* Email Config */} + + +
+ Email Configuration +

+ Configure SMTP settings for sending system emails and notifications. +

+
+ +
+ +
+
+
+
+ +

{currentConfig.EMAIL_HOST || 'Not configured'}

+
+
+ +

{currentConfig.EMAIL_PORT || 'Not configured'}

+
+
+ +

{currentConfig.EMAIL_HOST_USER || 'Not configured'}

+
+
+ +

{currentConfig.EMAIL_FROM_ADDRESS || 'Not configured'}

+
+
+
+
+
+
+ + {/* Data Retention */} + + +
+ Data Retention +

+ Set retention periods for different types of data before automatic cleanup. +

+
+ +
+ +
+
+
+
+ +

{currentConfig.ORDER_DATA_RETENTION || 90} days

+
+
+ +

{currentConfig.SHIPMENT_DATA_RETENTION || 90} days

+
+
+ +

{currentConfig.API_LOGS_DATA_RETENTION || 30} days

+
+
+
+
+
+
+ + {/* API Keys */} + + +
+ Address Validation & Autocomplete +

+ Configure third-party services for address validation and autocomplete functionality. +

+
+ +
+ +
+
+
+ +

+ {currentConfig.GOOGLE_CLOUD_API_KEY ? '••••••••' : 'Not configured'} +

+
+
+ +

+ {currentConfig.CANADAPOST_ADDRESS_COMPLETE_API_KEY ? '••••••••' : 'Not configured'} +

+
+
+
+
+
+
+ + setEditSection(null)} + configs={currentConfig} + onUpdate={handleUpdate} + /> +
+ ); +} + +function EditDialog({ + section, + onClose, + configs, + onUpdate +}: { + section: EditSection; + onClose: () => void; + configs: ConfigData; + onUpdate: (data: Partial) => void; +}) { + const [formData, setFormData] = useState(configs); + + useEffect(() => { + setFormData(configs); + }, [configs, section]); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + const data: Partial = {}; + + switch (section) { + case 'platform': + data.APP_NAME = formData.APP_NAME; + data.APP_WEBSITE = formData.APP_WEBSITE; + break; + case 'administration': + data.ALLOW_SIGNUP = formData.ALLOW_SIGNUP; + data.ALLOW_ADMIN_APPROVED_SIGNUP = formData.ALLOW_ADMIN_APPROVED_SIGNUP; + data.AUDIT_LOGGING = formData.AUDIT_LOGGING; + break; + case 'email': + data.EMAIL_USE_TLS = formData.EMAIL_USE_TLS; + data.EMAIL_HOST_USER = formData.EMAIL_HOST_USER; + data.EMAIL_HOST_PASSWORD = formData.EMAIL_HOST_PASSWORD; + data.EMAIL_HOST = formData.EMAIL_HOST; + data.EMAIL_PORT = formData.EMAIL_PORT; + data.EMAIL_FROM_ADDRESS = formData.EMAIL_FROM_ADDRESS; + break; + case 'data_retention': + data.ORDER_DATA_RETENTION = formData.ORDER_DATA_RETENTION; + data.TRACKER_DATA_RETENTION = formData.TRACKER_DATA_RETENTION; + data.SHIPMENT_DATA_RETENTION = formData.SHIPMENT_DATA_RETENTION; + data.API_LOGS_DATA_RETENTION = formData.API_LOGS_DATA_RETENTION; + break; + case 'api_keys': + data.GOOGLE_CLOUD_API_KEY = formData.GOOGLE_CLOUD_API_KEY; + data.CANADAPOST_ADDRESS_COMPLETE_API_KEY = formData.CANADAPOST_ADDRESS_COMPLETE_API_KEY; + break; + case 'features': + data.ALLOW_MULTI_ACCOUNT = formData.ALLOW_MULTI_ACCOUNT; + data.ADMIN_DASHBOARD = formData.ADMIN_DASHBOARD; + data.MULTI_ORGANIZATIONS = formData.MULTI_ORGANIZATIONS; + data.DOCUMENTS_MANAGEMENT = formData.DOCUMENTS_MANAGEMENT; + data.DATA_IMPORT_EXPORT = formData.DATA_IMPORT_EXPORT; + data.PERSIST_SDK_TRACING = formData.PERSIST_SDK_TRACING; + data.WORKFLOW_MANAGEMENT = formData.WORKFLOW_MANAGEMENT; + data.ORDERS_MANAGEMENT = formData.ORDERS_MANAGEMENT; + data.APPS_MANAGEMENT = formData.APPS_MANAGEMENT; + break; + } + + onUpdate(data); + }; + + const handleChange = (key: keyof ConfigData, value: any) => { + setFormData(prev => ({ ...prev, [key]: value })); + }; + + const renderContent = () => { + switch (section) { + case 'administration': + return ( +
+
+
+ +

Allow user signup

+
+ handleChange('ALLOW_SIGNUP', checked)} + /> +
+
+
+ +

User signup requires admin approval

+
+ handleChange('ALLOW_ADMIN_APPROVED_SIGNUP', checked)} + /> +
+
+
+ +

Enable audit logging for system activities

+
+ handleChange('AUDIT_LOGGING', checked)} + /> +
+
+ ); + + case 'email': + return ( +
+
+ + handleChange("EMAIL_HOST", e.target.value)} + /> +
+
+ + handleChange("EMAIL_PORT", Number(e.target.value))} + /> +
+
+ + handleChange("EMAIL_HOST_USER", e.target.value)} + /> +
+
+ + handleChange("EMAIL_HOST_PASSWORD", e.target.value)} + /> +
+
+ + handleChange("EMAIL_FROM_ADDRESS", e.target.value)} + /> +
+
+ handleChange("EMAIL_USE_TLS", checked)} + /> + +
+
+ ); + + case 'data_retention': + return ( +
+
+ + handleChange("ORDER_DATA_RETENTION", Number(e.target.value))} + /> +
+
+ + handleChange("SHIPMENT_DATA_RETENTION", Number(e.target.value))} + /> +
+
+ + handleChange("API_LOGS_DATA_RETENTION", Number(e.target.value))} + /> +
+
+ ); + + case 'api_keys': + return ( +
+
+ + handleChange("GOOGLE_CLOUD_API_KEY", e.target.value)} + /> +
+
+ + handleChange("CANADAPOST_ADDRESS_COMPLETE_API_KEY", e.target.value)} + /> +
+
+ ); + + case 'features': + return ( +
+
+
+ +

Allow users to have multiple accounts

+
+ handleChange("ALLOW_MULTI_ACCOUNT", checked)} + /> +
+
+
+ +

Enable admin dashboard access

+
+ handleChange("ADMIN_DASHBOARD", checked)} + /> +
+
+
+ +

Enable multi-organization support

+
+ handleChange("MULTI_ORGANIZATIONS", checked)} + /> +
+
+
+ +

Enable documents management

+
+ handleChange("DOCUMENTS_MANAGEMENT", checked)} + /> +
+
+
+ +

Enable data import/export

+
+ handleChange("DATA_IMPORT_EXPORT", checked)} + /> +
+
+
+ +

Persist SDK tracing

+
+ handleChange("PERSIST_SDK_TRACING", checked)} + /> +
+
+
+ +

Enable workflow management

+
+ handleChange("WORKFLOW_MANAGEMENT", checked)} + /> +
+
+
+ +

Enable orders management functionality

+
+ handleChange("ORDERS_MANAGEMENT", checked)} + /> +
+
+
+ +

Enable apps management functionality

+
+ handleChange("APPS_MANAGEMENT", checked)} + /> +
+
+ ); + + case 'platform': + return ( +
+
+ + handleChange("APP_NAME", e.target.value)} + /> +
+
+ + handleChange("APP_WEBSITE", e.target.value)} + /> +
+
+ ); + + default: + return null; + } + }; + + const titles = { + administration: 'Edit Administration Settings', + email: 'Edit Email Settings', + data_retention: 'Edit Data Retention Settings', + api_keys: 'Edit API Keys', + features: 'Edit Features', + platform: 'Edit Platform Details', + }; + + if (!section) return null; + + return ( + onClose()}> + + + {titles[section]} + + Update your platform settings. + + +
+ {renderContent()} + + + +
+
+
+ ); +} diff --git a/packages/admin/modules/users-permissions/index.tsx b/packages/admin/modules/staff/index.tsx similarity index 100% rename from packages/admin/modules/users-permissions/index.tsx rename to packages/admin/modules/staff/index.tsx diff --git a/packages/core/context/main.ts b/packages/core/context/main.ts index 32c5156b1..fcf789c9e 100644 --- a/packages/core/context/main.ts +++ b/packages/core/context/main.ts @@ -41,7 +41,7 @@ export async function loadMetadata() { // Attempt connection to the karrio API to retrieve the API metadata const API_URL = await getAPIURL(); - logger.debug("loadMetadata", API_URL); + logger.debug({ action: "> loadMetadata", API_URL }); const { data: metadata, error } = await axios .get(url$`${API_URL}`, { @@ -49,6 +49,7 @@ export async function loadMetadata() { }) .then((res) => ({ data: res.data, error: null })) .catch((e) => { + console.log("loadMetadata", e); const code = AUTH_HTTP_CODES.includes(e.response?.status) ? ServerErrorCode.API_AUTH_ERROR : ServerErrorCode.API_CONNECTION_ERROR; @@ -161,8 +162,8 @@ async function getAPIURL(metadata?: Metadata) { : null; const APIURL = !!TENANT_ENV_KEY ? (tenant?.api_domains || []).find((d) => - d.includes(TENANT_ENV_KEY as string), - ) + d.includes(TENANT_ENV_KEY as string), + ) : (tenant?.api_domains || [])[0]; return (!!APIURL ? APIURL : KARRIO_URL) as string; diff --git a/packages/core/layouts/public-layout.tsx b/packages/core/layouts/public-layout.tsx index 02680ab9e..874b59891 100644 --- a/packages/core/layouts/public-layout.tsx +++ b/packages/core/layouts/public-layout.tsx @@ -14,6 +14,8 @@ export default async function Layout({ const { metadata } = await loadMetadata(); const pageProps = { metadata }; + console.log(metadata, "metadata"); + return ( <> diff --git a/packages/insiders/components/carrier-connection-dialog.tsx b/packages/insiders/components/carrier-connection-dialog.tsx index af1f9fcc0..a2341674f 100644 --- a/packages/insiders/components/carrier-connection-dialog.tsx +++ b/packages/insiders/components/carrier-connection-dialog.tsx @@ -27,33 +27,39 @@ import { Switch } from "./ui/switch"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import * as z from "zod"; -import { GetSystemConnections_system_carrier_connections as BaseConnection } from "@karrio/types/graphql/admin/types"; +import { GetSystemConnections_system_carrier_connections_edges_node, CarrierNameEnum } from "@karrio/types/graphql/admin/types"; import { useAPIMetadata } from "@karrio/hooks/api-metadata"; -import { useState } from "react"; +import { useState, useEffect } from "react"; import { ChevronDown, ChevronUp } from "lucide-react"; import { MetadataEditor } from "./ui/metadata-editor"; +import { isEqual } from "lodash"; -type Connection = BaseConnection & { +type Connection = Omit & { credentials?: Record; config?: Record; + metadata?: Record; }; const formSchema = z.object({ - id: z.string(), - carrier_name: z.string(), - display_name: z.string(), - test_mode: z.boolean(), + carrier_name: z.nativeEnum(CarrierNameEnum), + carrier_id: z.string(), active: z.boolean(), capabilities: z.array(z.string()), - credentials: z.record(z.any()).optional(), - config: z.record(z.any()).optional(), + credentials: z.record(z.any()).refine( + (credentials) => true, // Will be validated in areCredentialsValid + { message: "Please fill in all required fields" } + ), + config: z.record(z.any()), + metadata: z.record(z.any()), }); +type FormData = z.infer; + interface CarrierConnectionDialogProps { open: boolean; onOpenChange: (open: boolean) => void; selectedConnection: Connection | null; - onSubmit: (values: z.infer) => void; + onSubmit: (values: FormData) => void; } export function CarrierConnectionDialog({ @@ -65,37 +71,96 @@ export function CarrierConnectionDialog({ const { references } = useAPIMetadata(); const [isConfigOpen, setIsConfigOpen] = useState(false); const [isMetadataOpen, setIsMetadataOpen] = useState(false); + const [initialValues, setInitialValues] = useState(null); + + const defaultValues: FormData = { + carrier_name: "" as CarrierNameEnum, + carrier_id: "", + active: false, + capabilities: [], + credentials: {}, + config: {}, + metadata: {}, + }; - const form = useForm>({ + const form = useForm({ resolver: zodResolver(formSchema), - defaultValues: { - id: "", - carrier_name: "", - display_name: "", - test_mode: false, - active: false, - capabilities: [], - credentials: {}, - config: {}, - }, + defaultValues, }); + // Track form changes + const carrierName = form.watch("carrier_name"); + const formState = form.formState; + const formValues = form.watch(); + const isDirty = initialValues ? !isEqual(formValues, initialValues) : false; + + // Check if required credentials are filled + const areCredentialsValid = () => { + const carrierName = form.getValues("carrier_name"); + const credentials = form.getValues("credentials"); + const fields = references?.connection_fields?.[carrierName] || {}; + + return Object.entries(fields).every(([key, field]) => { + if (field.required) { + const value = credentials?.[key]; + return value !== undefined && value !== "" && value !== null; + } + return true; + }); + }; + + const isValid = formState.isValid && areCredentialsValid(); + + // Initialize form values + useEffect(() => { + if (!open) { + form.reset(defaultValues); + setInitialValues(null); + setIsConfigOpen(false); + setIsMetadataOpen(false); + return; + } + + if (selectedConnection) { + const values: FormData = { + carrier_name: selectedConnection.carrier_name as CarrierNameEnum, + carrier_id: selectedConnection.carrier_id, + active: selectedConnection.active, + capabilities: selectedConnection.capabilities || [], + credentials: selectedConnection.credentials || {}, + config: selectedConnection.config || {}, + metadata: selectedConnection.metadata || {}, + }; + form.reset(values); + setInitialValues(values); + } else { + form.reset(defaultValues); + setInitialValues(defaultValues); + } + }, [open, selectedConnection]); + + // Handle carrier change + useEffect(() => { + if (!carrierName || selectedConnection || !open) return; + + const fields = references?.connection_fields?.[carrierName] || {}; + const defaultCredentials = Object.entries(fields).reduce( + (acc, [key, field]) => ({ + ...acc, + [key]: field.default || "", + }), + {} + ); + form.setValue("credentials", defaultCredentials); + }, [carrierName, selectedConnection, open]); + const handleModalClose = () => { - setIsConfigOpen(false); - setIsMetadataOpen(false); + // Reset form first + form.reset(defaultValues); + // Close modal in next frame requestAnimationFrame(() => { - form.reset({ - id: "", - carrier_name: "", - display_name: "", - test_mode: false, - active: false, - capabilities: [], - credentials: {}, - config: {}, - }); + onOpenChange(false); }); - onOpenChange(false); }; const formatLabel = (label: string) => { @@ -108,46 +173,59 @@ export function CarrierConnectionDialog({ const renderCredentialFields = () => { const carrierName = form.watch("carrier_name"); const fields = references?.connection_fields?.[carrierName] || {}; + const credentials = form.watch("credentials"); - return Object.entries(fields).map(([key, field]) => ( - ( - - {formatLabel(field.name)} - - {field.type === "string" && !field.enum ? ( - - ) : field.type === "string" && field.enum ? ( - - ) : field.type === "boolean" ? ( - - ) : null} - - - - )} - /> - )); + return Object.entries(fields) + .filter(([key]) => key !== "display_name") + .map(([key, field]) => { + const fieldValue = credentials?.[key] || ""; + return ( + ( + + + {formatLabel(field.name)} + {field.required && *} + + + {field.type === "string" && !field.enum ? ( + + ) : field.type === "string" && field.enum ? ( + + ) : field.type === "boolean" ? ( +
+ + {formatLabel(field.name)} +
+ ) : null} +
+ +
+ )} + /> + ); + }); }; const renderConfigFields = () => { @@ -172,7 +250,7 @@ export function CarrierConnectionDialog({ control={form.control} name={`config.${key}`} render={({ field: formField }) => ( - + {formatLabel(config.name)} {config.type === "string" && !config.enum ? ( @@ -180,7 +258,7 @@ export function CarrierConnectionDialog({ ) : config.type === "string" && config.enum ? ( ) : config.type === "boolean" ? ( - +
+ + {formatLabel(config.name)} +
) : null}
@@ -341,9 +422,38 @@ export function CarrierConnectionDialog({ ); }; + const handleSubmit = (values: FormData) => { + // Create base data + const baseData = { + carrier_name: values.carrier_name, + carrier_id: values.carrier_id, + active: values.active, + capabilities: values.capabilities, + credentials: values.credentials, + config: values.config || {}, + metadata: values.metadata || {}, + }; + + // Call onSubmit with the appropriate data + onSubmit(baseData); + }; + return ( - !open && handleModalClose()}> - + { + if (!value) { + handleModalClose(); + } else { + onOpenChange(true); + } + }} + > + handleModalClose()} + onInteractOutside={() => handleModalClose()} + > {selectedConnection ? "Edit Connection" : "Add Connection"} @@ -355,7 +465,7 @@ export function CarrierConnectionDialog({
@@ -366,11 +476,17 @@ export function CarrierConnectionDialog({ name="carrier_name" render={({ field }) => ( - Carrier + + Carrier * + @@ -407,23 +525,6 @@ export function CarrierConnectionDialog({ />
- ( - - - - - Test Mode - - - )} - /> - - Active + Active )} @@ -449,29 +550,29 @@ export function CarrierConnectionDialog({ {Object.keys( references?.connection_configs?.[ - form.watch("carrier_name") + form.watch("carrier_name") ] || {}, ).length > 0 && ( -
- + {isConfigOpen && ( +
+ {renderConfigFields()} +
)} - - {isConfigOpen && ( -
- {renderConfigFields()} -
- )} -
- )} +
+ )}
- + diff --git a/packages/insiders/components/rate-sheet-dialog.tsx b/packages/insiders/components/rate-sheet-dialog.tsx index 10d7570e9..ad7d7d749 100644 --- a/packages/insiders/components/rate-sheet-dialog.tsx +++ b/packages/insiders/components/rate-sheet-dialog.tsx @@ -1,11 +1,15 @@ -import { RateSheetModalEditor } from "@karrio/ui/modals/rate-sheet-editor"; import { Dialog, DialogContent } from "./ui/dialog"; +import { Button } from "./ui/button"; +import { X } from "lucide-react"; +import { cn } from "@karrio/insiders/lib/utils"; +import { RateSheetEditor } from "./rate-sheet-editor"; interface RateSheetDialogProps { open: boolean; onOpenChange: (open: boolean) => void; selectedRateSheet?: any; onSubmit: (values: any) => Promise; + isLoading?: boolean; } export function RateSheetDialog({ @@ -13,17 +17,68 @@ export function RateSheetDialog({ onOpenChange, selectedRateSheet, onSubmit, + isLoading, }: RateSheetDialogProps) { + if (!open) return null; + return ( - - - } - header={selectedRateSheet ? "Edit Rate Sheet" : "Add Rate Sheet"} - sheet={selectedRateSheet} - onSubmit={onSubmit} - /> - - +
+
+
+ + +
+

+ {selectedRateSheet ? "Edit rate sheet" : "Create rate sheet"} +

+
+ +
+ + +
+
+ +
+
+ +
+ +
+
+
Preview
+
+ {/* Preview content will go here */} +
+ Rate sheet preview will be shown here +
+
+
+
+
+
+
); } diff --git a/packages/insiders/components/rate-sheet-editor.tsx b/packages/insiders/components/rate-sheet-editor.tsx new file mode 100644 index 000000000..a5b3fae3e --- /dev/null +++ b/packages/insiders/components/rate-sheet-editor.tsx @@ -0,0 +1,322 @@ +import { CarrierNameEnum } from "@karrio/types/graphql/admin/types"; +import { Input } from "./ui/input"; +import { Label } from "./ui/label"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select"; +import { Button } from "./ui/button"; +import { useState } from "react"; +import { cn } from "@karrio/insiders/lib/utils"; +import { Loader2, Plus } from "lucide-react"; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./ui/table"; +import { ScrollArea } from "./ui/scroll-area"; +import CodeMirror from "@uiw/react-codemirror"; +import { json } from "@codemirror/lang-json"; + +interface RateSheetEditorProps { + sheet?: any; + onSubmit: (values: any) => Promise; + isLoading?: boolean; +} + +const DEFAULT_SERVICE = { + service_name: "STANDARD Courier", + service_code: "standard_courier", + carrier_service_code: null, + description: null, + active: true, + currency: "AUD", + transit_days: 1, + transit_time: 4, + max_width: 50, + max_height: 50, + max_length: 50, + dimension_unit: "CM", + weight_unit: "KG", + zones: [ + { + label: null, + rate: 36.63, + min_weight: null, + max_weight: null, + transit_days: null, + cities: ["ALEXANDER HEIGHTS"], + postal_codes: null, + country_codes: null, + }, + ], +}; + +const DEFAULT_STATE = { + carrier_name: "generic", + name: "", + services: [DEFAULT_SERVICE], +}; + +export function RateSheetEditor({ sheet, onSubmit, isLoading }: RateSheetEditorProps) { + const [formData, setFormData] = useState(sheet || DEFAULT_STATE); + const [selectedService, setSelectedService] = useState(0); + const [jsonMode, setJsonMode] = useState(false); + + const handleBasicInfoChange = (field: string) => (e: any) => { + setFormData((prev: any) => ({ + ...prev, + [field]: e.target.value || e, + })); + }; + + const handleServiceChange = (field: string) => (e: any) => { + setFormData((prev: any) => ({ + ...prev, + services: prev.services.map((service: any, idx: number) => + idx === selectedService + ? { ...service, [field]: e.target.value || e } + : service + ), + })); + }; + + const handleJsonChange = (value: string) => { + try { + const parsed = JSON.parse(value); + setFormData(parsed); + } catch (error) { + // Handle JSON parse error + } + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + await onSubmit(formData); + }; + + const addService = () => { + setFormData((prev: any) => ({ + ...prev, + services: [...prev.services, { ...DEFAULT_SERVICE }], + })); + setSelectedService(formData.services.length); + }; + + const removeService = (index: number) => { + setFormData((prev: any) => ({ + ...prev, + services: prev.services.filter((_: any, idx: number) => idx !== index), + })); + setSelectedService(Math.max(0, selectedService - 1)); + }; + + return ( +
+
+
+

Basic Information

+

+ Configure the basic settings for your rate sheet. +

+
+
+
+ + +
+ +
+ + handleBasicInfoChange("name")(e.target.value)} + placeholder="Enter rate sheet name" + /> +
+
+
+
+ +
+

Services

+

+ Configure shipping services and their rates. +

+
+
+
+
+ {formData.services.map((service: any, idx: number) => ( +
setSelectedService(idx)} + > +
+
+

{service.service_name}

+

{service.service_code}

+
+ {formData.services.length > 1 && ( + + )} +
+
+ ))} + +
+
+ +
+ {formData.services[selectedService] && ( +
+
+
+ + handleServiceChange("service_name")(e.target.value)} + /> +
+
+ + handleServiceChange("service_code")(e.target.value)} + /> +
+
+ +
+
+ + +
+
+ + handleServiceChange("transit_days")(parseInt(e.target.value))} + /> +
+
+ +
+
+ + handleServiceChange("max_width")(parseInt(e.target.value))} + /> +
+
+ + handleServiceChange("max_height")(parseInt(e.target.value))} + /> +
+
+ + handleServiceChange("max_length")(parseInt(e.target.value))} + /> +
+
+ +
+
+ + +
+
+ + + + Rate + Min Weight + Max Weight + Cities + + + + {formData.services[selectedService].zones.map((zone: any, idx: number) => ( + + {zone.rate} + {zone.min_weight || '-'} + {zone.max_weight || '-'} + {zone.cities?.join(", ") || '-'} + + ))} + +
+
+
+
+ )} +
+
+
+
+
+
+ ); +} diff --git a/packages/trpc/server/router/admin.ts b/packages/trpc/server/router/admin.ts index ee68a806f..1cd205e7c 100644 --- a/packages/trpc/server/router/admin.ts +++ b/packages/trpc/server/router/admin.ts @@ -62,6 +62,63 @@ import type { DisableOrganizationAccount, DeleteOrganizationAccount, } from "@karrio/types/graphql/admin/types"; +import { TRPCError } from "@trpc/server"; +import { CarrierNameEnum } from "@karrio/types/graphql/admin/types"; + +interface GraphQLError { + field: string; + messages: string[]; +} + +function handleErrors(response: any) { + // If the response itself is an error (e.g. network error) + if (response instanceof Error) { + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: response.message || "A network error occurred", + cause: response + }); + } + + // Handle GraphQL response errors (from client) + if (response?.errors) { + const errorMessage = response.errors + .map((error: any) => { + if (error.message) return error.message; + if (error.field && error.messages) return `${error.field}: ${error.messages.join(", ")}`; + return JSON.stringify(error); + }) + .join("\n"); + throw new TRPCError({ + code: "BAD_REQUEST", + message: errorMessage, + cause: response.errors + }); + } + + // Handle mutation/query specific errors (from resolvers) + if (response?.response?.errors) { + const errorMessage = response.response.errors + .map((error: any) => error.message || JSON.stringify(error)) + .join("\n"); + throw new TRPCError({ + code: "BAD_REQUEST", + message: errorMessage, + cause: response.response.errors + }); + } + + // Handle unexpected response structure + if (response && typeof response === 'object' && 'message' in response) { + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: response.message || "An unexpected server error occurred", + cause: response + }); + } + + return response; +} const usersRouter = router({ list: protectedProcedure @@ -81,13 +138,17 @@ const usersRouter = router({ ) .query(async ({ ctx, input }) => { const client = ctx.karrio; - const { users } = await client.admin.request( - gqlstr(GET_USERS), - { - filter: input.filter, - }, - ); - return users; + try { + const { users } = await client.admin.request( + gqlstr(GET_USERS), + { + filter: input.filter, + }, + ); + return users; + } catch (error) { + handleErrors(error); + } }), create: protectedProcedure .input( @@ -104,13 +165,18 @@ const usersRouter = router({ ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { create_user } = await client.admin.request( - gqlstr(CREATE_USER), - { - data: input.data, - }, - ); - return create_user; + try { + const { create_user } = await client.admin.request( + gqlstr(CREATE_USER), + { + data: input.data, + }, + ); + handleErrors(create_user); + return create_user.user; + } catch (error) { + handleErrors(error); + } }), update: protectedProcedure .input( @@ -128,13 +194,18 @@ const usersRouter = router({ ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { update_user } = await client.admin.request( - gqlstr(UPDATE_USER), - { - data: input.data, - }, - ); - return update_user; + try { + const { update_user } = await client.admin.request( + gqlstr(UPDATE_USER), + { + data: input.data, + }, + ); + handleErrors(update_user); + return update_user.user; + } catch (error) { + handleErrors(error); + } }), remove: protectedProcedure .input( @@ -146,52 +217,92 @@ const usersRouter = router({ ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { remove_user } = await client.admin.request( - gqlstr(REMOVE_USER), - { - data: input.data, - }, - ); - return remove_user; + try { + const { remove_user } = await client.admin.request( + gqlstr(REMOVE_USER), + { + data: input.data, + }, + ); + handleErrors(remove_user); + return { id: remove_user.id }; + } catch (error) { + handleErrors(error); + } }), }); const configsRouter = router({ list: protectedProcedure.query(async ({ ctx }) => { const client = ctx.karrio; - const { configs } = await client.admin.request( - gqlstr(GET_CONFIGS), - ); - return configs; + try { + const { configs } = await client.admin.request( + gqlstr(GET_CONFIGS), + ); + return configs; + } catch (error) { + handleErrors(error); + } }), update: protectedProcedure .input( z.object({ data: z.object({ + // Platform Config + APP_NAME: z.string().optional(), + APP_WEBSITE: z.string().optional(), + + // Email Config EMAIL_USE_TLS: z.boolean().optional(), EMAIL_HOST_USER: z.string().optional(), EMAIL_HOST_PASSWORD: z.string().optional(), EMAIL_HOST: z.string().optional(), EMAIL_PORT: z.number().optional(), EMAIL_FROM_ADDRESS: z.string().optional(), + + // Address Validation Service GOOGLE_CLOUD_API_KEY: z.string().optional(), CANADAPOST_ADDRESS_COMPLETE_API_KEY: z.string().optional(), + + // Data Retention ORDER_DATA_RETENTION: z.number().optional(), TRACKER_DATA_RETENTION: z.number().optional(), SHIPMENT_DATA_RETENTION: z.number().optional(), API_LOGS_DATA_RETENTION: z.number().optional(), + + // System Settings + AUDIT_LOGGING: z.boolean().optional(), + ALLOW_SIGNUP: z.boolean().optional(), + ALLOW_ADMIN_APPROVED_SIGNUP: z.boolean().optional(), + ALLOW_MULTI_ACCOUNT: z.boolean().optional(), + + // Feature Flags + ADMIN_DASHBOARD: z.boolean().optional(), + MULTI_ORGANIZATIONS: z.boolean().optional(), + ORDERS_MANAGEMENT: z.boolean().optional(), + APPS_MANAGEMENT: z.boolean().optional(), + DOCUMENTS_MANAGEMENT: z.boolean().optional(), + DATA_IMPORT_EXPORT: z.boolean().optional(), + WORKFLOW_MANAGEMENT: z.boolean().optional(), + PERSIST_SDK_TRACING: z.boolean().optional(), }), }), ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { update_configs } = await client.admin.request( - gqlstr(UPDATE_CONFIGS), - { - data: input.data, - }, - ); - return update_configs; + try { + const response = await client.admin.request( + gqlstr(UPDATE_CONFIGS), + { data: input.data }, + ); + if (!response || !response.update_configs) { + throw new Error('Invalid response from server'); + } + handleErrors(response.update_configs); + return response.update_configs.configs; + } catch (error) { + handleErrors(error); + } }), }); @@ -212,25 +323,33 @@ const surchargesRouter = router({ ) .query(async ({ ctx, input }) => { const client = ctx.karrio; - const { surcharges } = await client.admin.request( - gqlstr(GET_SURCHARGES), - { - filter: input.filter, - }, - ); - return surcharges; + try { + const { surcharges } = await client.admin.request( + gqlstr(GET_SURCHARGES), + { + filter: input.filter, + }, + ); + return surcharges; + } catch (error) { + handleErrors(error); + } }), get: protectedProcedure .input(z.object({ id: z.string() })) .query(async ({ ctx, input }) => { const client = ctx.karrio; - const { surcharge } = await client.admin.request( - gqlstr(GET_SURCHARGE), - { - id: input.id, - }, - ); - return surcharge; + try { + const { surcharge } = await client.admin.request( + gqlstr(GET_SURCHARGE), + { + id: input.id, + }, + ); + return surcharge; + } catch (error) { + handleErrors(error); + } }), create: protectedProcedure .input( @@ -247,13 +366,18 @@ const surchargesRouter = router({ ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { create_surcharge } = await client.admin.request( - gqlstr(CREATE_SURCHARGE), - { - data: input.data, - }, - ); - return create_surcharge; + try { + const { create_surcharge } = await client.admin.request( + gqlstr(CREATE_SURCHARGE), + { + data: input.data, + }, + ); + handleErrors(create_surcharge); + return create_surcharge.surcharge; + } catch (error) { + handleErrors(error); + } }), update: protectedProcedure .input( @@ -271,13 +395,18 @@ const surchargesRouter = router({ ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { update_surcharge } = await client.admin.request( - gqlstr(UPDATE_SURCHARGE), - { - data: input.data, - }, - ); - return update_surcharge; + try { + const { update_surcharge } = await client.admin.request( + gqlstr(UPDATE_SURCHARGE), + { + data: input.data, + }, + ); + handleErrors(update_surcharge); + return update_surcharge.surcharge; + } catch (error) { + handleErrors(error); + } }), delete: protectedProcedure .input( @@ -289,13 +418,18 @@ const surchargesRouter = router({ ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { delete_surcharge } = await client.admin.request( - gqlstr(DELETE_SURCHARGE), - { - data: input.data, - }, - ); - return delete_surcharge; + try { + const { delete_surcharge } = await client.admin.request( + gqlstr(DELETE_SURCHARGE), + { + data: input.data, + }, + ); + handleErrors(delete_surcharge); + return { id: delete_surcharge.id }; + } catch (error) { + handleErrors(error); + } }), }); @@ -312,25 +446,33 @@ const rateSheetsRouter = router({ ) .query(async ({ ctx, input }) => { const client = ctx.karrio; - const { rate_sheets } = await client.admin.request( - gqlstr(GET_RATE_SHEETS), - { - filter: input.filter, - }, - ); - return rate_sheets; + try { + const { rate_sheets } = await client.admin.request( + gqlstr(GET_RATE_SHEETS), + { + filter: input.filter, + }, + ); + return rate_sheets; + } catch (error) { + handleErrors(error); + } }), get: protectedProcedure .input(z.object({ id: z.string() })) .query(async ({ ctx, input }) => { const client = ctx.karrio; - const { rate_sheet } = await client.admin.request( - gqlstr(GET_RATE_SHEET), - { - id: input.id, - }, - ); - return rate_sheet; + try { + const { rate_sheet } = await client.admin.request( + gqlstr(GET_RATE_SHEET), + { + id: input.id, + }, + ); + return rate_sheet; + } catch (error) { + handleErrors(error); + } }), create: protectedProcedure .input( @@ -339,60 +481,25 @@ const rateSheetsRouter = router({ name: z.string(), carrier_name: z.string(), metadata: z.record(z.any()).optional(), - services: z - .array( - z.object({ - service_name: z.string(), - service_code: z.string(), - carrier_service_code: z.string().optional(), - description: z.string().optional(), - active: z.boolean().optional(), - currency: z.string(), - transit_days: z.number().optional(), - transit_time: z.number().optional(), - max_width: z.number().optional(), - max_height: z.number().optional(), - max_length: z.number().optional(), - dimension_unit: z.string().optional(), - max_weight: z.number().optional(), - weight_unit: z.string().optional(), - domicile: z.boolean().optional(), - international: z.boolean().optional(), - metadata: z.record(z.any()).optional(), - zones: z - .array( - z.object({ - label: z.string(), - rate: z.number(), - min_weight: z.number().optional(), - max_weight: z.number().optional(), - transit_days: z.number().optional(), - transit_time: z.number().optional(), - radius: z.number().optional(), - latitude: z.number().optional(), - longitude: z.number().optional(), - cities: z.array(z.string()).optional(), - postal_codes: z.array(z.string()).optional(), - country_codes: z.array(z.string()).optional(), - }), - ) - .optional(), - }), - ) - .optional(), + services: z.array(z.any()).optional(), carriers: z.array(z.string()).optional(), }), }), ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { create_rate_sheet } = await client.admin.request( - gqlstr(CREATE_RATE_SHEET), - { - data: input.data, - }, - ); - return create_rate_sheet; + try { + const { create_rate_sheet } = await client.admin.request( + gqlstr(CREATE_RATE_SHEET), + { + data: input.data, + }, + ); + handleErrors(create_rate_sheet); + return create_rate_sheet.rate_sheet; + } catch (error) { + handleErrors(error); + } }), update: protectedProcedure .input( @@ -402,49 +509,7 @@ const rateSheetsRouter = router({ name: z.string().optional(), carrier_name: z.string().optional(), metadata: z.record(z.any()).optional(), - services: z - .array( - z.object({ - id: z.string().optional(), - service_name: z.string().optional(), - service_code: z.string().optional(), - carrier_service_code: z.string().optional(), - description: z.string().optional(), - active: z.boolean().optional(), - currency: z.string().optional(), - transit_days: z.number().optional(), - transit_time: z.number().optional(), - max_width: z.number().optional(), - max_height: z.number().optional(), - max_length: z.number().optional(), - dimension_unit: z.string().optional(), - max_weight: z.number().optional(), - weight_unit: z.string().optional(), - domicile: z.boolean().optional(), - international: z.boolean().optional(), - metadata: z.record(z.any()).optional(), - zones: z - .array( - z.object({ - id: z.string().optional(), - label: z.string().optional(), - rate: z.number().optional(), - min_weight: z.number().optional(), - max_weight: z.number().optional(), - transit_days: z.number().optional(), - transit_time: z.number().optional(), - radius: z.number().optional(), - latitude: z.number().optional(), - longitude: z.number().optional(), - cities: z.array(z.string()).optional(), - postal_codes: z.array(z.string()).optional(), - country_codes: z.array(z.string()).optional(), - }), - ) - .optional(), - }), - ) - .optional(), + services: z.array(z.any()).optional(), carriers: z.array(z.string()).optional(), remove_missing_services: z.boolean().optional(), }), @@ -452,13 +517,18 @@ const rateSheetsRouter = router({ ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { update_rate_sheet } = await client.admin.request( - gqlstr(UPDATE_RATE_SHEET), - { - data: input.data, - }, - ); - return update_rate_sheet; + try { + const { update_rate_sheet } = await client.admin.request( + gqlstr(UPDATE_RATE_SHEET), + { + data: input.data, + }, + ); + handleErrors(update_rate_sheet); + return update_rate_sheet.rate_sheet; + } catch (error) { + handleErrors(error); + } }), update_service_zone: protectedProcedure .input( @@ -486,14 +556,18 @@ const rateSheetsRouter = router({ ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { update_service_zone } = - await client.admin.request( + try { + const { update_service_zone } = await client.admin.request( gqlstr(UPDATE_SERVICE_ZONE), { data: input.data, }, ); - return update_service_zone; + handleErrors(update_service_zone); + return update_service_zone.rate_sheet; + } catch (error) { + handleErrors(error); + } }), delete: protectedProcedure .input( @@ -505,13 +579,18 @@ const rateSheetsRouter = router({ ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { delete_rate_sheet } = await client.admin.request( - gqlstr(DELETE_RATE_SHEET), - { - data: input.data, - }, - ); - return delete_rate_sheet; + try { + const { delete_rate_sheet } = await client.admin.request( + gqlstr(DELETE_RATE_SHEET), + { + data: input.data, + }, + ); + handleErrors(delete_rate_sheet); + return { id: delete_rate_sheet.id }; + } catch (error) { + handleErrors(error); + } }), }); @@ -524,6 +603,8 @@ const systemConnectionsRouter = router({ metadata_key: z.string().optional(), metadata_value: z.string().optional(), carrier_name: z.array(z.string()).optional(), + offset: z.number().optional(), + first: z.number().optional(), }).optional(), }) ) @@ -535,68 +616,85 @@ const systemConnectionsRouter = router({ filter: input.filter, }, ); - return system_carrier_connections; }), get: protectedProcedure .input(z.object({ id: z.string() })) .query(async ({ ctx, input }) => { const client = ctx.karrio; - const { system_carrier_connection } = - await client.admin.request( - gqlstr(GET_SYSTEM_CONNECTION), - { id: input.id }, - ); + const { system_carrier_connection } = await client.admin.request( + gqlstr(GET_SYSTEM_CONNECTION), + { id: input.id }, + ); return system_carrier_connection; }), create: protectedProcedure .input( z.object({ data: z.object({ - carrier_name: z.string(), - display_name: z.string(), - test_mode: z.boolean().optional(), + carrier_name: z.nativeEnum(CarrierNameEnum), + carrier_id: z.string(), + credentials: z.record(z.any()), active: z.boolean().optional(), - capabilities: z.array(z.string()).optional(), - credentials: z.record(z.any()).optional(), config: z.record(z.any()).optional(), metadata: z.record(z.any()).optional(), + capabilities: z.array(z.string()).optional(), }), }), ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { create_system_carrier_connection } = - await client.admin.request( - gqlstr(CREATE_SYSTEM_CONNECTION), - { data: input.data }, - ); - return create_system_carrier_connection; + const { create_system_carrier_connection } = await client.admin.request( + gqlstr(CREATE_SYSTEM_CONNECTION), + { + data: { + carrier_name: input.data.carrier_name, + carrier_id: input.data.carrier_id, + credentials: input.data.credentials, + active: input.data.active, + config: input.data.config || {}, + metadata: input.data.metadata || {}, + capabilities: input.data.capabilities || [], + } + }, + ); + + handleErrors(create_system_carrier_connection.errors); + return create_system_carrier_connection.connection; }), update: protectedProcedure .input( z.object({ data: z.object({ id: z.string(), - carrier_name: z.string().optional(), - display_name: z.string().optional(), - test_mode: z.boolean().optional(), active: z.boolean().optional(), - capabilities: z.array(z.string()).optional(), + carrier_id: z.string().optional(), credentials: z.record(z.any()).optional(), config: z.record(z.any()).optional(), metadata: z.record(z.any()).optional(), + capabilities: z.array(z.string()).optional(), }), }), ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { update_system_carrier_connection } = - await client.admin.request( - gqlstr(UPDATE_SYSTEM_CONNECTION), - { data: input.data }, - ); - return update_system_carrier_connection; + const { update_system_carrier_connection } = await client.admin.request( + gqlstr(UPDATE_SYSTEM_CONNECTION), + { + data: { + id: input.data.id, + active: input.data.active, + carrier_id: input.data.carrier_id, + credentials: input.data.credentials, + config: input.data.config, + metadata: input.data.metadata, + capabilities: input.data.capabilities, + } + }, + ); + + handleErrors(update_system_carrier_connection.errors); + return update_system_carrier_connection.connection; }), delete: protectedProcedure .input( @@ -608,12 +706,13 @@ const systemConnectionsRouter = router({ ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { delete_system_carrier_connection } = - await client.admin.request( - gqlstr(DELETE_SYSTEM_CONNECTION), - { data: input.data }, - ); - return delete_system_carrier_connection; + const { delete_system_carrier_connection } = await client.admin.request( + gqlstr(DELETE_SYSTEM_CONNECTION), + { data: input.data }, + ); + + handleErrors(delete_system_carrier_connection.errors); + return { id: delete_system_carrier_connection.id }; }), }); @@ -632,13 +731,17 @@ const organizationAccountsRouter = router({ ) .query(async ({ ctx, input }) => { const client = ctx.karrio; - const { accounts } = await client.admin.request( - gqlstr(GET_ACCOUNTS), - { - filter: input.filter, - }, - ); - return accounts; + try { + const { accounts } = await client.admin.request( + gqlstr(GET_ACCOUNTS), + { + filter: input.filter, + }, + ); + return accounts; + } catch (error) { + handleErrors(error); + } }), create: protectedProcedure .input( @@ -651,12 +754,17 @@ const organizationAccountsRouter = router({ ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { create_organization_account } = - await client.admin.request( - gqlstr(CREATE_ORGANIZATION_ACCOUNT), - { data: input.data }, - ); - return create_organization_account; + try { + const { create_organization_account } = + await client.admin.request( + gqlstr(CREATE_ORGANIZATION_ACCOUNT), + { data: input.data }, + ); + handleErrors(create_organization_account); + return create_organization_account.account; + } catch (error) { + handleErrors(error); + } }), update: protectedProcedure .input( @@ -670,12 +778,17 @@ const organizationAccountsRouter = router({ ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { update_organization_account } = - await client.admin.request( - gqlstr(UPDATE_ORGANIZATION_ACCOUNT), - { data: input.data }, - ); - return update_organization_account; + try { + const { update_organization_account } = + await client.admin.request( + gqlstr(UPDATE_ORGANIZATION_ACCOUNT), + { data: input.data }, + ); + handleErrors(update_organization_account); + return update_organization_account.account; + } catch (error) { + handleErrors(error); + } }), disable: protectedProcedure .input( @@ -687,12 +800,17 @@ const organizationAccountsRouter = router({ ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { disable_organization_account } = - await client.admin.request( - gqlstr(DISABLE_ORGANIZATION_ACCOUNT), - { data: input.data }, - ); - return disable_organization_account; + try { + const { disable_organization_account } = + await client.admin.request( + gqlstr(DISABLE_ORGANIZATION_ACCOUNT), + { data: input.data }, + ); + handleErrors(disable_organization_account); + return disable_organization_account.account; + } catch (error) { + handleErrors(error); + } }), delete: protectedProcedure .input( @@ -704,12 +822,17 @@ const organizationAccountsRouter = router({ ) .mutation(async ({ ctx, input }) => { const client = ctx.karrio; - const { delete_organization_account } = - await client.admin.request( - gqlstr(DELETE_ORGANIZATION_ACCOUNT), - { data: input.data }, - ); - return delete_organization_account; + try { + const { delete_organization_account } = + await client.admin.request( + gqlstr(DELETE_ORGANIZATION_ACCOUNT), + { data: input.data }, + ); + handleErrors(delete_organization_account); + return delete_organization_account.account; + } catch (error) { + handleErrors(error); + } }), }); @@ -727,14 +850,18 @@ const permissionGroupsRouter = router({ ) .query(async ({ ctx, input }) => { const client = ctx.karrio; - const { permission_groups } = - await client.admin.request( - gqlstr(GET_PERMISSION_GROUPS), - { - filter: input.filter, - }, - ); - return permission_groups; + try { + const { permission_groups } = + await client.admin.request( + gqlstr(GET_PERMISSION_GROUPS), + { + filter: input.filter, + }, + ); + return permission_groups; + } catch (error) { + handleErrors(error); + } }), }); diff --git a/packages/types/graphql/admin/queries.ts b/packages/types/graphql/admin/queries.ts index f5f85f94a..82aafbd7b 100644 --- a/packages/types/graphql/admin/queries.ts +++ b/packages/types/graphql/admin/queries.ts @@ -236,22 +236,46 @@ export const REMOVE_USER = gql` // Config Operations // ----------------------------------------------------------- //#region - export const GET_CONFIGS = gql` query GetConfigs { configs { + # Platform Config + APP_NAME + APP_WEBSITE + + # Email Config EMAIL_USE_TLS EMAIL_HOST_USER EMAIL_HOST_PASSWORD EMAIL_HOST EMAIL_PORT EMAIL_FROM_ADDRESS + + # Address Validation Service GOOGLE_CLOUD_API_KEY CANADAPOST_ADDRESS_COMPLETE_API_KEY + + # Data Retention ORDER_DATA_RETENTION TRACKER_DATA_RETENTION SHIPMENT_DATA_RETENTION API_LOGS_DATA_RETENTION + + # System Settings + AUDIT_LOGGING + ALLOW_SIGNUP + ALLOW_ADMIN_APPROVED_SIGNUP + ALLOW_MULTI_ACCOUNT + + # Feature Flags + ADMIN_DASHBOARD + MULTI_ORGANIZATIONS + ORDERS_MANAGEMENT + APPS_MANAGEMENT + DOCUMENTS_MANAGEMENT + DATA_IMPORT_EXPORT + WORKFLOW_MANAGEMENT + PERSIST_SDK_TRACING } } `; @@ -264,18 +288,43 @@ export const UPDATE_CONFIGS = gql` messages } configs { + # Platform Config + APP_NAME + APP_WEBSITE + + # Email Config EMAIL_USE_TLS EMAIL_HOST_USER EMAIL_HOST_PASSWORD EMAIL_HOST EMAIL_PORT EMAIL_FROM_ADDRESS + + # Address Validation Service GOOGLE_CLOUD_API_KEY CANADAPOST_ADDRESS_COMPLETE_API_KEY + + # Data Retention ORDER_DATA_RETENTION TRACKER_DATA_RETENTION SHIPMENT_DATA_RETENTION API_LOGS_DATA_RETENTION + + # System Settings + AUDIT_LOGGING + ALLOW_SIGNUP + ALLOW_ADMIN_APPROVED_SIGNUP + ALLOW_MULTI_ACCOUNT + + # Feature Flags + ADMIN_DASHBOARD + MULTI_ORGANIZATIONS + ORDERS_MANAGEMENT + APPS_MANAGEMENT + DOCUMENTS_MANAGEMENT + DATA_IMPORT_EXPORT + WORKFLOW_MANAGEMENT + PERSIST_SDK_TRACING } } } diff --git a/packages/types/graphql/admin/types.ts b/packages/types/graphql/admin/types.ts index 4cbba1c71..34fb2ec67 100644 --- a/packages/types/graphql/admin/types.ts +++ b/packages/types/graphql/admin/types.ts @@ -1,1981 +1,2026 @@ - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL query operation: GetSystemConnections -// ==================================================== - -export interface GetSystemConnections_system_carrier_connections_edges_node { - id: string; - carrier_name: string; - carrier_id: string; - display_name: string; - test_mode: boolean; - active: boolean; - capabilities: string[]; - credentials: any; - config: any | null; - metadata: any | null; - object_type: string | null; -} - -export interface GetSystemConnections_system_carrier_connections_edges { - node: GetSystemConnections_system_carrier_connections_edges_node; - cursor: string; -} - -export interface GetSystemConnections_system_carrier_connections_page_info { - has_next_page: boolean; - has_previous_page: boolean; - start_cursor: string | null; - end_cursor: string | null; -} - -export interface GetSystemConnections_system_carrier_connections { - edges: GetSystemConnections_system_carrier_connections_edges[]; - page_info: GetSystemConnections_system_carrier_connections_page_info; -} - -export interface GetSystemConnections { - system_carrier_connections: GetSystemConnections_system_carrier_connections; -} - -export interface GetSystemConnectionsVariables { - filter?: CarrierFilter | null; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL query operation: GetSystemConnection -// ==================================================== - -export interface GetSystemConnection_system_carrier_connection { - id: string; - carrier_name: string; - carrier_id: string; - display_name: string; - test_mode: boolean; - active: boolean; - capabilities: string[]; - credentials: any; - config: any | null; - metadata: any | null; - object_type: string | null; -} - -export interface GetSystemConnection { - system_carrier_connection: GetSystemConnection_system_carrier_connection | null; -} - -export interface GetSystemConnectionVariables { - id: string; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: CreateSystemConnection -// ==================================================== - -export interface CreateSystemConnection_create_system_carrier_connection_errors { - field: string; - messages: string[]; -} - -export interface CreateSystemConnection_create_system_carrier_connection_connection { - id: string; - carrier_name: string; - carrier_id: string; - display_name: string; - test_mode: boolean; - active: boolean; - capabilities: string[]; - credentials: any; - config: any | null; - metadata: any | null; - object_type: string | null; -} - -export interface CreateSystemConnection_create_system_carrier_connection { - errors: CreateSystemConnection_create_system_carrier_connection_errors[] | null; - connection: CreateSystemConnection_create_system_carrier_connection_connection | null; -} - -export interface CreateSystemConnection { - create_system_carrier_connection: CreateSystemConnection_create_system_carrier_connection; -} - -export interface CreateSystemConnectionVariables { - data: CreateConnectionMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: UpdateSystemConnection -// ==================================================== - -export interface UpdateSystemConnection_update_system_carrier_connection_errors { - field: string; - messages: string[]; -} - -export interface UpdateSystemConnection_update_system_carrier_connection_connection { - id: string; - carrier_name: string; - carrier_id: string; - display_name: string; - test_mode: boolean; - active: boolean; - capabilities: string[]; - credentials: any; - config: any | null; - metadata: any | null; - object_type: string | null; -} - -export interface UpdateSystemConnection_update_system_carrier_connection { - errors: UpdateSystemConnection_update_system_carrier_connection_errors[] | null; - connection: UpdateSystemConnection_update_system_carrier_connection_connection | null; -} - -export interface UpdateSystemConnection { - update_system_carrier_connection: UpdateSystemConnection_update_system_carrier_connection; -} - -export interface UpdateSystemConnectionVariables { - data: UpdateConnectionMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: DeleteSystemConnection -// ==================================================== - -export interface DeleteSystemConnection_delete_system_carrier_connection_errors { - field: string; - messages: string[]; -} - -export interface DeleteSystemConnection_delete_system_carrier_connection { - errors: DeleteSystemConnection_delete_system_carrier_connection_errors[] | null; - id: string; -} - -export interface DeleteSystemConnection { - delete_system_carrier_connection: DeleteSystemConnection_delete_system_carrier_connection; -} - -export interface DeleteSystemConnectionVariables { - data: DeleteConnectionMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL query operation: GetMe -// ==================================================== - -export interface GetMe_me { - id: number; - email: string; - full_name: string; - is_staff: boolean; - is_active: boolean; - is_superuser: boolean | null; - last_login: any | null; - permissions: string[] | null; -} - -export interface GetMe { - me: GetMe_me; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL query operation: GetUser -// ==================================================== - -export interface GetUser_user { - id: number; - email: string; - full_name: string; - is_staff: boolean; - is_active: boolean; - is_superuser: boolean | null; - last_login: any | null; - permissions: string[] | null; -} - -export interface GetUser { - user: GetUser_user | null; -} - -export interface GetUserVariables { - email: string; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL query operation: GetUsers -// ==================================================== - -export interface GetUsers_users_edges_node { - id: number; - email: string; - full_name: string; - is_staff: boolean; - is_active: boolean; - is_superuser: boolean | null; - last_login: any | null; - permissions: string[] | null; -} - -export interface GetUsers_users_edges { - node: GetUsers_users_edges_node; - cursor: string; -} - -export interface GetUsers_users_page_info { - count: number; - has_next_page: boolean; - has_previous_page: boolean; - start_cursor: string | null; - end_cursor: string | null; -} - -export interface GetUsers_users { - edges: GetUsers_users_edges[]; - page_info: GetUsers_users_page_info; -} - -export interface GetUsers { - users: GetUsers_users; -} - -export interface GetUsersVariables { - filter?: UserFilter | null; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: CreateUser -// ==================================================== - -export interface CreateUser_create_user_user { - id: number; - email: string; - full_name: string; - is_staff: boolean; - is_active: boolean; - is_superuser: boolean | null; - last_login: any | null; - permissions: string[] | null; -} - -export interface CreateUser_create_user_errors { - field: string; - messages: string[]; -} - -export interface CreateUser_create_user { - user: CreateUser_create_user_user | null; - errors: CreateUser_create_user_errors[] | null; -} - -export interface CreateUser { - create_user: CreateUser_create_user; -} - -export interface CreateUserVariables { - data: CreateUserMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: UpdateUser -// ==================================================== - -export interface UpdateUser_update_user_user { - id: number; - email: string; - full_name: string; - is_staff: boolean; - is_active: boolean; - is_superuser: boolean | null; - last_login: any | null; - permissions: string[] | null; -} - -export interface UpdateUser_update_user_errors { - field: string; - messages: string[]; -} - -export interface UpdateUser_update_user { - user: UpdateUser_update_user_user | null; - errors: UpdateUser_update_user_errors[] | null; -} - -export interface UpdateUser { - update_user: UpdateUser_update_user; -} - -export interface UpdateUserVariables { - data: UpdateUserMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: RemoveUser -// ==================================================== - -export interface RemoveUser_remove_user_errors { - field: string; - messages: string[]; -} - -export interface RemoveUser_remove_user { - errors: RemoveUser_remove_user_errors[] | null; - id: number; -} - -export interface RemoveUser { - remove_user: RemoveUser_remove_user; -} - -export interface RemoveUserVariables { - data: DeleteUserMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL query operation: GetConfigs -// ==================================================== - -export interface GetConfigs_configs { - EMAIL_USE_TLS: boolean | null; - EMAIL_HOST_USER: string | null; - EMAIL_HOST_PASSWORD: string | null; - EMAIL_HOST: string | null; - EMAIL_PORT: number | null; - EMAIL_FROM_ADDRESS: string | null; - GOOGLE_CLOUD_API_KEY: string | null; - CANADAPOST_ADDRESS_COMPLETE_API_KEY: string | null; - ORDER_DATA_RETENTION: number | null; - TRACKER_DATA_RETENTION: number | null; - SHIPMENT_DATA_RETENTION: number | null; - API_LOGS_DATA_RETENTION: number | null; -} - -export interface GetConfigs { - configs: GetConfigs_configs; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: UpdateConfigs -// ==================================================== - -export interface UpdateConfigs_update_configs_errors { - field: string; - messages: string[]; -} - -export interface UpdateConfigs_update_configs_configs { - EMAIL_USE_TLS: boolean | null; - EMAIL_HOST_USER: string | null; - EMAIL_HOST_PASSWORD: string | null; - EMAIL_HOST: string | null; - EMAIL_PORT: number | null; - EMAIL_FROM_ADDRESS: string | null; - GOOGLE_CLOUD_API_KEY: string | null; - CANADAPOST_ADDRESS_COMPLETE_API_KEY: string | null; - ORDER_DATA_RETENTION: number | null; - TRACKER_DATA_RETENTION: number | null; - SHIPMENT_DATA_RETENTION: number | null; - API_LOGS_DATA_RETENTION: number | null; -} - -export interface UpdateConfigs_update_configs { - errors: UpdateConfigs_update_configs_errors[] | null; - configs: UpdateConfigs_update_configs_configs | null; -} - -export interface UpdateConfigs { - update_configs: UpdateConfigs_update_configs; -} - -export interface UpdateConfigsVariables { - data: InstanceConfigMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL query operation: GetSurcharge -// ==================================================== - -export interface GetSurcharge_surcharge_carrier_accounts { - id: string; - active: boolean; - carrier_id: string; -} - -export interface GetSurcharge_surcharge { - id: string; - name: string; - amount: number; - surcharge_type: string; - object_type: string; - active: boolean; - services: string[]; - carriers: string[]; - carrier_accounts: GetSurcharge_surcharge_carrier_accounts[]; -} - -export interface GetSurcharge { - surcharge: GetSurcharge_surcharge | null; -} - -export interface GetSurchargeVariables { - id: string; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL query operation: GetSurcharges -// ==================================================== - -export interface GetSurcharges_surcharges_edges_node_carrier_accounts { - id: string; - active: boolean; - carrier_id: string; -} - -export interface GetSurcharges_surcharges_edges_node { - id: string; - name: string; - amount: number; - surcharge_type: string; - object_type: string; - active: boolean; - services: string[]; - carriers: string[]; - carrier_accounts: GetSurcharges_surcharges_edges_node_carrier_accounts[]; -} - -export interface GetSurcharges_surcharges_edges { - node: GetSurcharges_surcharges_edges_node; - cursor: string; -} - -export interface GetSurcharges_surcharges_page_info { - count: number; - has_next_page: boolean; - has_previous_page: boolean; - start_cursor: string | null; - end_cursor: string | null; -} - -export interface GetSurcharges_surcharges { - edges: GetSurcharges_surcharges_edges[]; - page_info: GetSurcharges_surcharges_page_info; -} - -export interface GetSurcharges { - surcharges: GetSurcharges_surcharges; -} - -export interface GetSurchargesVariables { - filter?: SurchargeFilter | null; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: CreateSurcharge -// ==================================================== - -export interface CreateSurcharge_create_surcharge_errors { - field: string; - messages: string[]; -} - -export interface CreateSurcharge_create_surcharge_surcharge_carrier_accounts { - id: string; - active: boolean; - carrier_id: string; -} - -export interface CreateSurcharge_create_surcharge_surcharge { - id: string; - name: string; - amount: number; - surcharge_type: string; - object_type: string; - active: boolean; - services: string[]; - carriers: string[]; - carrier_accounts: CreateSurcharge_create_surcharge_surcharge_carrier_accounts[]; -} - -export interface CreateSurcharge_create_surcharge { - errors: CreateSurcharge_create_surcharge_errors[] | null; - surcharge: CreateSurcharge_create_surcharge_surcharge | null; -} - -export interface CreateSurcharge { - create_surcharge: CreateSurcharge_create_surcharge; -} - -export interface CreateSurchargeVariables { - data: CreateSurchargeMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: UpdateSurcharge -// ==================================================== - -export interface UpdateSurcharge_update_surcharge_errors { - field: string; - messages: string[]; -} - -export interface UpdateSurcharge_update_surcharge_surcharge_carrier_accounts { - id: string; - active: boolean; - carrier_id: string; -} - -export interface UpdateSurcharge_update_surcharge_surcharge { - id: string; - name: string; - amount: number; - surcharge_type: string; - object_type: string; - active: boolean; - services: string[]; - carriers: string[]; - carrier_accounts: UpdateSurcharge_update_surcharge_surcharge_carrier_accounts[]; -} - -export interface UpdateSurcharge_update_surcharge { - errors: UpdateSurcharge_update_surcharge_errors[] | null; - surcharge: UpdateSurcharge_update_surcharge_surcharge | null; -} - -export interface UpdateSurcharge { - update_surcharge: UpdateSurcharge_update_surcharge; -} - -export interface UpdateSurchargeVariables { - data: UpdateSurchargeMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: DeleteSurcharge -// ==================================================== - -export interface DeleteSurcharge_delete_surcharge_errors { - field: string; - messages: string[]; -} - -export interface DeleteSurcharge_delete_surcharge { - errors: DeleteSurcharge_delete_surcharge_errors[] | null; - id: string; -} - -export interface DeleteSurcharge { - delete_surcharge: DeleteSurcharge_delete_surcharge; -} - -export interface DeleteSurchargeVariables { - data: DeleteMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL query operation: GetRateSheet -// ==================================================== - -export interface GetRateSheet_rate_sheet_services_zones { - object_type: string; - label: string | null; - rate: number | null; - min_weight: number | null; - max_weight: number | null; - transit_days: number | null; - transit_time: number | null; - radius: number | null; - latitude: number | null; - longitude: number | null; - cities: string[] | null; - postal_codes: string[] | null; - country_codes: CountryCodeEnum[] | null; -} - -export interface GetRateSheet_rate_sheet_services { - id: string; - object_type: string; - service_name: string | null; - service_code: string | null; - carrier_service_code: string | null; - description: string | null; - active: boolean | null; - currency: CurrencyCodeEnum | null; - transit_days: number | null; - transit_time: number | null; - max_width: number | null; - max_height: number | null; - max_length: number | null; - dimension_unit: DimensionUnitEnum | null; - max_weight: number | null; - weight_unit: WeightUnitEnum | null; - domicile: boolean | null; - international: boolean | null; - metadata: any | null; - zones: GetRateSheet_rate_sheet_services_zones[]; -} - -export interface GetRateSheet_rate_sheet_carriers { - id: string; - carrier_id: string; - carrier_name: string; - display_name: string; - active: boolean; - is_system: boolean; - test_mode: boolean; - capabilities: string[]; -} - -export interface GetRateSheet_rate_sheet { - id: string; - name: string; - slug: string; - carrier_name: CarrierNameEnum; - object_type: string; - metadata: any | null; - services: GetRateSheet_rate_sheet_services[]; - carriers: GetRateSheet_rate_sheet_carriers[]; -} - -export interface GetRateSheet { - rate_sheet: GetRateSheet_rate_sheet | null; -} - -export interface GetRateSheetVariables { - id: string; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL query operation: GetRateSheets -// ==================================================== - -export interface GetRateSheets_rate_sheets_edges_node_services { - id: string; - service_name: string | null; - service_code: string | null; - carrier_service_code: string | null; - description: string | null; - active: boolean | null; -} - -export interface GetRateSheets_rate_sheets_edges_node_carriers { - id: string; - carrier_id: string; - carrier_name: string; - display_name: string; - active: boolean; - is_system: boolean; - test_mode: boolean; - capabilities: string[]; -} - -export interface GetRateSheets_rate_sheets_edges_node { - id: string; - name: string; - slug: string; - carrier_name: CarrierNameEnum; - object_type: string; - metadata: any | null; - services: GetRateSheets_rate_sheets_edges_node_services[]; - carriers: GetRateSheets_rate_sheets_edges_node_carriers[]; -} - -export interface GetRateSheets_rate_sheets_edges { - node: GetRateSheets_rate_sheets_edges_node; - cursor: string; -} - -export interface GetRateSheets_rate_sheets_page_info { - count: number; - has_next_page: boolean; - has_previous_page: boolean; - start_cursor: string | null; - end_cursor: string | null; -} - -export interface GetRateSheets_rate_sheets { - edges: GetRateSheets_rate_sheets_edges[]; - page_info: GetRateSheets_rate_sheets_page_info; -} - -export interface GetRateSheets { - rate_sheets: GetRateSheets_rate_sheets; -} - -export interface GetRateSheetsVariables { - filter?: RateSheetFilter | null; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: CreateRateSheet -// ==================================================== - -export interface CreateRateSheet_create_rate_sheet_errors { - field: string; - messages: string[]; -} - -export interface CreateRateSheet_create_rate_sheet_rate_sheet_services_zones { - label: string | null; - rate: number | null; - min_weight: number | null; - max_weight: number | null; - transit_days: number | null; - transit_time: number | null; - radius: number | null; - latitude: number | null; - longitude: number | null; - cities: string[] | null; - postal_codes: string[] | null; - country_codes: CountryCodeEnum[] | null; -} - -export interface CreateRateSheet_create_rate_sheet_rate_sheet_services { - id: string; - service_name: string | null; - service_code: string | null; - carrier_service_code: string | null; - description: string | null; - active: boolean | null; - metadata: any | null; - zones: CreateRateSheet_create_rate_sheet_rate_sheet_services_zones[]; -} - -export interface CreateRateSheet_create_rate_sheet_rate_sheet_carriers { - id: string; - carrier_id: string; - carrier_name: string; - display_name: string; - active: boolean; - is_system: boolean; - test_mode: boolean; - capabilities: string[]; -} - -export interface CreateRateSheet_create_rate_sheet_rate_sheet { - id: string; - name: string; - slug: string; - carrier_name: CarrierNameEnum; - object_type: string; - metadata: any | null; - services: CreateRateSheet_create_rate_sheet_rate_sheet_services[]; - carriers: CreateRateSheet_create_rate_sheet_rate_sheet_carriers[]; -} - -export interface CreateRateSheet_create_rate_sheet { - errors: CreateRateSheet_create_rate_sheet_errors[] | null; - rate_sheet: CreateRateSheet_create_rate_sheet_rate_sheet | null; -} - -export interface CreateRateSheet { - create_rate_sheet: CreateRateSheet_create_rate_sheet; -} - -export interface CreateRateSheetVariables { - data: CreateRateSheetMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: UpdateRateSheet -// ==================================================== - -export interface UpdateRateSheet_update_rate_sheet_errors { - field: string; - messages: string[]; -} - -export interface UpdateRateSheet_update_rate_sheet_rate_sheet_services_zones { - label: string | null; - rate: number | null; - min_weight: number | null; - max_weight: number | null; - transit_days: number | null; - transit_time: number | null; - radius: number | null; - latitude: number | null; - longitude: number | null; - cities: string[] | null; - postal_codes: string[] | null; - country_codes: CountryCodeEnum[] | null; -} - -export interface UpdateRateSheet_update_rate_sheet_rate_sheet_services { - id: string; - service_name: string | null; - service_code: string | null; - carrier_service_code: string | null; - description: string | null; - active: boolean | null; - metadata: any | null; - zones: UpdateRateSheet_update_rate_sheet_rate_sheet_services_zones[]; -} - -export interface UpdateRateSheet_update_rate_sheet_rate_sheet_carriers { - id: string; - carrier_id: string; - carrier_name: string; - display_name: string; - active: boolean; - is_system: boolean; - test_mode: boolean; - capabilities: string[]; -} - -export interface UpdateRateSheet_update_rate_sheet_rate_sheet { - id: string; - name: string; - slug: string; - carrier_name: CarrierNameEnum; - object_type: string; - metadata: any | null; - services: UpdateRateSheet_update_rate_sheet_rate_sheet_services[]; - carriers: UpdateRateSheet_update_rate_sheet_rate_sheet_carriers[]; -} - -export interface UpdateRateSheet_update_rate_sheet { - errors: UpdateRateSheet_update_rate_sheet_errors[] | null; - rate_sheet: UpdateRateSheet_update_rate_sheet_rate_sheet | null; -} - -export interface UpdateRateSheet { - update_rate_sheet: UpdateRateSheet_update_rate_sheet; -} - -export interface UpdateRateSheetVariables { - data: UpdateRateSheetMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: UpdateServiceZone -// ==================================================== - -export interface UpdateServiceZone_update_service_zone_errors { - field: string; - messages: string[]; -} - -export interface UpdateServiceZone_update_service_zone_rate_sheet_services_zones { - label: string | null; - rate: number | null; - min_weight: number | null; - max_weight: number | null; - transit_days: number | null; - transit_time: number | null; - radius: number | null; - latitude: number | null; - longitude: number | null; - cities: string[] | null; - postal_codes: string[] | null; - country_codes: CountryCodeEnum[] | null; -} - -export interface UpdateServiceZone_update_service_zone_rate_sheet_services { - id: string; - zones: UpdateServiceZone_update_service_zone_rate_sheet_services_zones[]; -} - -export interface UpdateServiceZone_update_service_zone_rate_sheet { - id: string; - services: UpdateServiceZone_update_service_zone_rate_sheet_services[]; -} - -export interface UpdateServiceZone_update_service_zone { - errors: UpdateServiceZone_update_service_zone_errors[] | null; - rate_sheet: UpdateServiceZone_update_service_zone_rate_sheet | null; -} - -export interface UpdateServiceZone { - update_service_zone: UpdateServiceZone_update_service_zone; -} - -export interface UpdateServiceZoneVariables { - data: UpdateServiceZoneMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: DeleteRateSheet -// ==================================================== - -export interface DeleteRateSheet_delete_rate_sheet_errors { - field: string; - messages: string[]; -} - -export interface DeleteRateSheet_delete_rate_sheet { - errors: DeleteRateSheet_delete_rate_sheet_errors[] | null; - id: string; -} - -export interface DeleteRateSheet { - delete_rate_sheet: DeleteRateSheet_delete_rate_sheet; -} - -export interface DeleteRateSheetVariables { - data: DeleteMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL query operation: GetAccounts -// ==================================================== - -export interface GetAccounts_accounts_edges_node_usage { - members: number | null; - total_errors: number | null; - order_volume: number | null; - total_requests: number | null; - total_trackers: number | null; - total_shipments: number | null; - unfulfilled_orders: number | null; - total_shipping_spend: number | null; -} - -export interface GetAccounts_accounts_edges_node { - id: string; - name: string; - slug: string; - is_active: boolean; - created: any; - modified: any; - usage: GetAccounts_accounts_edges_node_usage; -} - -export interface GetAccounts_accounts_edges { - node: GetAccounts_accounts_edges_node; - cursor: string; -} - -export interface GetAccounts_accounts_page_info { - count: number; - has_next_page: boolean; - has_previous_page: boolean; - start_cursor: string | null; - end_cursor: string | null; -} - -export interface GetAccounts_accounts { - edges: GetAccounts_accounts_edges[]; - page_info: GetAccounts_accounts_page_info; -} - -export interface GetAccounts { - accounts: GetAccounts_accounts; -} - -export interface GetAccountsVariables { - filter?: AccountFilter | null; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: CreateOrganizationAccount -// ==================================================== - -export interface CreateOrganizationAccount_create_organization_account_account { - id: string; -} - -export interface CreateOrganizationAccount_create_organization_account_errors { - field: string; - messages: string[]; -} - -export interface CreateOrganizationAccount_create_organization_account { - account: CreateOrganizationAccount_create_organization_account_account | null; - errors: CreateOrganizationAccount_create_organization_account_errors[] | null; -} - -export interface CreateOrganizationAccount { - create_organization_account: CreateOrganizationAccount_create_organization_account; -} - -export interface CreateOrganizationAccountVariables { - data: CreateOrganizationAccountMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: UpdateOrganizationAccount -// ==================================================== - -export interface UpdateOrganizationAccount_update_organization_account_account { - id: string; -} - -export interface UpdateOrganizationAccount_update_organization_account_errors { - field: string; - messages: string[]; -} - -export interface UpdateOrganizationAccount_update_organization_account { - account: UpdateOrganizationAccount_update_organization_account_account | null; - errors: UpdateOrganizationAccount_update_organization_account_errors[] | null; -} - -export interface UpdateOrganizationAccount { - update_organization_account: UpdateOrganizationAccount_update_organization_account; -} - -export interface UpdateOrganizationAccountVariables { - data: UpdateOrganizationAccountMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: DisableOrganizationAccount -// ==================================================== - -export interface DisableOrganizationAccount_disable_organization_account_account { - id: string; -} - -export interface DisableOrganizationAccount_disable_organization_account_errors { - field: string; - messages: string[]; -} - -export interface DisableOrganizationAccount_disable_organization_account { - account: DisableOrganizationAccount_disable_organization_account_account | null; - errors: DisableOrganizationAccount_disable_organization_account_errors[] | null; -} - -export interface DisableOrganizationAccount { - disable_organization_account: DisableOrganizationAccount_disable_organization_account; -} - -export interface DisableOrganizationAccountVariables { - data: DisableOrganizationAccountMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL mutation operation: DeleteOrganizationAccount -// ==================================================== - -export interface DeleteOrganizationAccount_delete_organization_account_account { - id: string; -} - -export interface DeleteOrganizationAccount_delete_organization_account_errors { - field: string; - messages: string[]; -} - -export interface DeleteOrganizationAccount_delete_organization_account { - account: DeleteOrganizationAccount_delete_organization_account_account | null; - errors: DeleteOrganizationAccount_delete_organization_account_errors[] | null; -} - -export interface DeleteOrganizationAccount { - delete_organization_account: DeleteOrganizationAccount_delete_organization_account; -} - -export interface DeleteOrganizationAccountVariables { - data: DeleteOrganizationAccountMutationInput; -} - - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL query operation: GetPermissionGroups -// ==================================================== - -export interface GetPermissionGroups_permission_groups_edges_node { - id: number; - name: string; - permissions: string[] | null; -} - -export interface GetPermissionGroups_permission_groups_edges { - node: GetPermissionGroups_permission_groups_edges_node; - cursor: string; -} - -export interface GetPermissionGroups_permission_groups_page_info { - count: number; - has_next_page: boolean; - has_previous_page: boolean; - start_cursor: string | null; - end_cursor: string | null; -} - -export interface GetPermissionGroups_permission_groups { - edges: GetPermissionGroups_permission_groups_edges[]; - page_info: GetPermissionGroups_permission_groups_page_info; -} - -export interface GetPermissionGroups { - permission_groups: GetPermissionGroups_permission_groups; -} - -export interface GetPermissionGroupsVariables { - filter?: PermissionGroupFilter | null; -} - -/* tslint:disable */ -// This file was automatically generated and should not be edited. - -//============================================================== -// START Enums and Input Objects -//============================================================== - -export enum CarrierNameEnum { - allied_express = "allied_express", - allied_express_local = "allied_express_local", - amazon_shipping = "amazon_shipping", - aramex = "aramex", - asendia_us = "asendia_us", - australiapost = "australiapost", - boxknight = "boxknight", - bpost = "bpost", - canadapost = "canadapost", - canpar = "canpar", - chronopost = "chronopost", - colissimo = "colissimo", - dhl_express = "dhl_express", - dhl_parcel_de = "dhl_parcel_de", - dhl_poland = "dhl_poland", - dhl_universal = "dhl_universal", - dicom = "dicom", - dpd = "dpd", - dpdhl = "dpdhl", - easypost = "easypost", - easyship = "easyship", - eshipper = "eshipper", - fedex = "fedex", - fedex_ws = "fedex_ws", - freightcom = "freightcom", - generic = "generic", - geodis = "geodis", - hay_post = "hay_post", - laposte = "laposte", - locate2u = "locate2u", - nationex = "nationex", - purolator = "purolator", - roadie = "roadie", - royalmail = "royalmail", - sapient = "sapient", - seko = "seko", - sendle = "sendle", - tge = "tge", - tnt = "tnt", - ups = "ups", - usps = "usps", - usps_international = "usps_international", - usps_wt = "usps_wt", - usps_wt_international = "usps_wt_international", - zoom2u = "zoom2u", -} - -export enum SurchargeTypeEnum { - AMOUNT = "AMOUNT", - PERCENTAGE = "PERCENTAGE", -} - -export enum CurrencyCodeEnum { - AED = "AED", - AMD = "AMD", - ANG = "ANG", - AOA = "AOA", - ARS = "ARS", - AUD = "AUD", - AWG = "AWG", - AZN = "AZN", - BAM = "BAM", - BBD = "BBD", - BDT = "BDT", - BGN = "BGN", - BHD = "BHD", - BIF = "BIF", - BMD = "BMD", - BND = "BND", - BOB = "BOB", - BRL = "BRL", - BSD = "BSD", - BTN = "BTN", - BWP = "BWP", - BYN = "BYN", - BZD = "BZD", - CAD = "CAD", - CDF = "CDF", - CHF = "CHF", - CLP = "CLP", - CNY = "CNY", - COP = "COP", - CRC = "CRC", - CUC = "CUC", - CVE = "CVE", - CZK = "CZK", - DJF = "DJF", - DKK = "DKK", - DOP = "DOP", - DZD = "DZD", - EGP = "EGP", - ERN = "ERN", - ETB = "ETB", - EUR = "EUR", - FJD = "FJD", - GBP = "GBP", - GEL = "GEL", - GHS = "GHS", - GMD = "GMD", - GNF = "GNF", - GTQ = "GTQ", - GYD = "GYD", - HKD = "HKD", - HNL = "HNL", - HRK = "HRK", - HTG = "HTG", - HUF = "HUF", - IDR = "IDR", - ILS = "ILS", - INR = "INR", - IRR = "IRR", - ISK = "ISK", - JMD = "JMD", - JOD = "JOD", - JPY = "JPY", - KES = "KES", - KGS = "KGS", - KHR = "KHR", - KMF = "KMF", - KPW = "KPW", - KRW = "KRW", - KWD = "KWD", - KYD = "KYD", - KZT = "KZT", - LAK = "LAK", - LKR = "LKR", - LRD = "LRD", - LSL = "LSL", - LYD = "LYD", - MAD = "MAD", - MDL = "MDL", - MGA = "MGA", - MKD = "MKD", - MMK = "MMK", - MNT = "MNT", - MOP = "MOP", - MRO = "MRO", - MUR = "MUR", - MVR = "MVR", - MWK = "MWK", - MXN = "MXN", - MYR = "MYR", - MZN = "MZN", - NAD = "NAD", - NGN = "NGN", - NIO = "NIO", - NOK = "NOK", - NPR = "NPR", - NZD = "NZD", - OMR = "OMR", - PEN = "PEN", - PGK = "PGK", - PHP = "PHP", - PKR = "PKR", - PLN = "PLN", - PYG = "PYG", - QAR = "QAR", - RSD = "RSD", - RUB = "RUB", - RWF = "RWF", - SAR = "SAR", - SBD = "SBD", - SCR = "SCR", - SDG = "SDG", - SEK = "SEK", - SGD = "SGD", - SHP = "SHP", - SLL = "SLL", - SOS = "SOS", - SRD = "SRD", - SSP = "SSP", - STD = "STD", - SYP = "SYP", - SZL = "SZL", - THB = "THB", - TJS = "TJS", - TND = "TND", - TOP = "TOP", - TRY = "TRY", - TTD = "TTD", - TWD = "TWD", - TZS = "TZS", - UAH = "UAH", - USD = "USD", - UYU = "UYU", - UZS = "UZS", - VEF = "VEF", - VND = "VND", - VUV = "VUV", - WST = "WST", - XAF = "XAF", - XCD = "XCD", - XOF = "XOF", - XPF = "XPF", - YER = "YER", - ZAR = "ZAR", -} - -export enum DimensionUnitEnum { - CM = "CM", - IN = "IN", -} - -export enum WeightUnitEnum { - G = "G", - KG = "KG", - LB = "LB", - OZ = "OZ", -} - -export enum CountryCodeEnum { - AC = "AC", - AD = "AD", - AE = "AE", - AF = "AF", - AG = "AG", - AI = "AI", - AL = "AL", - AM = "AM", - AN = "AN", - AO = "AO", - AR = "AR", - AS = "AS", - AT = "AT", - AU = "AU", - AW = "AW", - AZ = "AZ", - BA = "BA", - BB = "BB", - BD = "BD", - BE = "BE", - BF = "BF", - BG = "BG", - BH = "BH", - BI = "BI", - BJ = "BJ", - BL = "BL", - BM = "BM", - BN = "BN", - BO = "BO", - BR = "BR", - BS = "BS", - BT = "BT", - BW = "BW", - BY = "BY", - BZ = "BZ", - CA = "CA", - CD = "CD", - CF = "CF", - CG = "CG", - CH = "CH", - CI = "CI", - CK = "CK", - CL = "CL", - CM = "CM", - CN = "CN", - CO = "CO", - CR = "CR", - CU = "CU", - CV = "CV", - CY = "CY", - CZ = "CZ", - DE = "DE", - DJ = "DJ", - DK = "DK", - DM = "DM", - DO = "DO", - DZ = "DZ", - EC = "EC", - EE = "EE", - EG = "EG", - EH = "EH", - ER = "ER", - ES = "ES", - ET = "ET", - FI = "FI", - FJ = "FJ", - FK = "FK", - FM = "FM", - FO = "FO", - FR = "FR", - GA = "GA", - GB = "GB", - GD = "GD", - GE = "GE", - GF = "GF", - GG = "GG", - GH = "GH", - GI = "GI", - GL = "GL", - GM = "GM", - GN = "GN", - GP = "GP", - GQ = "GQ", - GR = "GR", - GT = "GT", - GU = "GU", - GW = "GW", - GY = "GY", - HK = "HK", - HN = "HN", - HR = "HR", - HT = "HT", - HU = "HU", - IC = "IC", - ID = "ID", - IE = "IE", - IL = "IL", - IM = "IM", - IN = "IN", - IQ = "IQ", - IR = "IR", - IS = "IS", - IT = "IT", - JE = "JE", - JM = "JM", - JO = "JO", - JP = "JP", - KE = "KE", - KG = "KG", - KH = "KH", - KI = "KI", - KM = "KM", - KN = "KN", - KP = "KP", - KR = "KR", - KV = "KV", - KW = "KW", - KY = "KY", - KZ = "KZ", - LA = "LA", - LB = "LB", - LC = "LC", - LI = "LI", - LK = "LK", - LR = "LR", - LS = "LS", - LT = "LT", - LU = "LU", - LV = "LV", - LY = "LY", - MA = "MA", - MC = "MC", - MD = "MD", - ME = "ME", - MF = "MF", - MG = "MG", - MH = "MH", - MK = "MK", - ML = "ML", - MM = "MM", - MN = "MN", - MO = "MO", - MP = "MP", - MQ = "MQ", - MR = "MR", - MS = "MS", - MT = "MT", - MU = "MU", - MV = "MV", - MW = "MW", - MX = "MX", - MY = "MY", - MZ = "MZ", - NA = "NA", - NC = "NC", - NE = "NE", - NG = "NG", - NI = "NI", - NL = "NL", - NO = "NO", - NP = "NP", - NR = "NR", - NU = "NU", - NZ = "NZ", - OM = "OM", - PA = "PA", - PE = "PE", - PF = "PF", - PG = "PG", - PH = "PH", - PK = "PK", - PL = "PL", - PR = "PR", - PT = "PT", - PW = "PW", - PY = "PY", - QA = "QA", - RE = "RE", - RO = "RO", - RS = "RS", - RU = "RU", - RW = "RW", - SA = "SA", - SB = "SB", - SC = "SC", - SD = "SD", - SE = "SE", - SG = "SG", - SH = "SH", - SI = "SI", - SK = "SK", - SL = "SL", - SM = "SM", - SN = "SN", - SO = "SO", - SR = "SR", - SS = "SS", - ST = "ST", - SV = "SV", - SX = "SX", - SY = "SY", - SZ = "SZ", - TC = "TC", - TD = "TD", - TG = "TG", - TH = "TH", - TJ = "TJ", - TL = "TL", - TN = "TN", - TO = "TO", - TR = "TR", - TT = "TT", - TV = "TV", - TW = "TW", - TZ = "TZ", - UA = "UA", - UG = "UG", - US = "US", - UY = "UY", - UZ = "UZ", - VA = "VA", - VC = "VC", - VE = "VE", - VG = "VG", - VI = "VI", - VN = "VN", - VU = "VU", - WS = "WS", - XB = "XB", - XC = "XC", - XE = "XE", - XM = "XM", - XN = "XN", - XS = "XS", - XY = "XY", - YE = "YE", - YT = "YT", - ZA = "ZA", - ZM = "ZM", - ZW = "ZW", -} - -// null -export interface CarrierFilter { - active?: boolean | null; - metadata_key?: string | null; - metadata_value?: string | null; - carrier_name?: string[] | null; -} - -// null -export interface CreateConnectionMutationInput { - carrier_name: CarrierNameEnum; - carrier_id: string; - credentials: any; - active?: boolean | null; - config?: any | null; - metadata?: any | null; - capabilities?: string[] | null; -} - -// null -export interface UpdateConnectionMutationInput { - id: string; - active?: boolean | null; - carrier_id?: string | null; - credentials?: any | null; - config?: any | null; - metadata?: any | null; - capabilities?: string[] | null; -} - -// null -export interface DeleteConnectionMutationInput { - id: string; -} - -// null -export interface UserFilter { - offset?: number | null; - first?: number | null; - id?: string | null; - email?: string | null; - is_staff?: boolean | null; - is_active?: boolean | null; - is_superuser?: boolean | null; - order_by?: string | null; -} - -// null -export interface CreateUserMutationInput { - email: string; - password1: string; - password2: string; - redirect_url: string; - full_name?: string | null; - is_staff?: boolean | null; - is_active?: boolean | null; - is_superuser?: boolean | null; - organization_id?: string | null; - permissions?: string[] | null; -} - -// null -export interface UpdateUserMutationInput { - id: number; - email?: string | null; - full_name?: string | null; - is_staff?: boolean | null; - is_active?: boolean | null; - is_superuser?: boolean | null; - permissions?: string[] | null; -} - -// null -export interface DeleteUserMutationInput { - id: number; -} - -// null -export interface InstanceConfigMutationInput { - EMAIL_USE_TLS?: boolean | null; - EMAIL_HOST_USER?: string | null; - EMAIL_HOST_PASSWORD?: string | null; - EMAIL_HOST?: string | null; - EMAIL_PORT?: number | null; - EMAIL_FROM_ADDRESS?: string | null; - GOOGLE_CLOUD_API_KEY?: string | null; - CANADAPOST_ADDRESS_COMPLETE_API_KEY?: string | null; - ORDER_DATA_RETENTION?: number | null; - TRACKER_DATA_RETENTION?: number | null; - SHIPMENT_DATA_RETENTION?: number | null; - API_LOGS_DATA_RETENTION?: number | null; -} - -// null -export interface SurchargeFilter { - offset?: number | null; - first?: number | null; - id?: string | null; - name?: string | null; - active?: boolean | null; - surcharge_type?: SurchargeTypeEnum | null; -} - -// null -export interface CreateSurchargeMutationInput { - name: string; - amount: number; - surcharge_type: SurchargeTypeEnum; - active?: boolean | null; - carriers?: string[] | null; - services?: string[] | null; - organizations?: string[] | null; - carrier_accounts?: string[] | null; -} - -// null -export interface UpdateSurchargeMutationInput { - name?: string | null; - amount?: number | null; - surcharge_type?: SurchargeTypeEnum | null; - active?: boolean | null; - carriers?: string[] | null; - services?: string[] | null; - organizations?: string[] | null; - carrier_accounts?: string[] | null; - id: string; -} - -// null -export interface DeleteMutationInput { - id: string; -} - -// null -export interface RateSheetFilter { - offset?: number | null; - first?: number | null; - keyword?: string | null; -} - -// null -export interface CreateRateSheetMutationInput { - name: string; - carrier_name: CarrierNameEnum; - services?: CreateServiceLevelInput[] | null; - carriers?: string[] | null; - metadata?: any | null; -} - -// null -export interface CreateServiceLevelInput { - service_name: string; - service_code: string; - currency: CurrencyCodeEnum; - zones: ServiceZoneInput[]; - carrier_service_code?: string | null; - description?: string | null; - active?: boolean | null; - transit_days?: number | null; - transit_time?: number | null; - max_width?: number | null; - max_height?: number | null; - max_length?: number | null; - dimension_unit?: DimensionUnitEnum | null; - min_weight?: number | null; - max_weight?: number | null; - weight_unit?: WeightUnitEnum | null; - domicile?: boolean | null; - international?: boolean | null; - metadata?: any | null; -} - -// null -export interface ServiceZoneInput { - rate: number; - label?: string | null; - min_weight?: number | null; - max_weight?: number | null; - transit_days?: number | null; - transit_time?: number | null; - radius?: number | null; - latitude?: number | null; - longitude?: number | null; - cities?: string[] | null; - postal_codes?: string[] | null; - country_codes?: string[] | null; -} - -// null -export interface UpdateRateSheetMutationInput { - id: string; - name?: string | null; - services?: UpdateServiceLevelInput[] | null; - carriers?: string[] | null; - remove_missing_services?: boolean | null; - metadata?: any | null; -} - -// null -export interface UpdateServiceLevelInput { - service_name?: string | null; - service_code?: string | null; - currency?: CurrencyCodeEnum | null; - zones?: UpdateServiceZoneInput[] | null; - carrier_service_code?: string | null; - description?: string | null; - active?: boolean | null; - transit_days?: number | null; - transit_time?: number | null; - max_width?: number | null; - max_height?: number | null; - max_length?: number | null; - dimension_unit?: DimensionUnitEnum | null; - min_weight?: number | null; - max_weight?: number | null; - weight_unit?: WeightUnitEnum | null; - domicile?: boolean | null; - international?: boolean | null; - metadata?: any | null; - id?: string | null; -} - -// null -export interface UpdateServiceZoneInput { - rate?: number | null; - label?: string | null; - min_weight?: number | null; - max_weight?: number | null; - transit_days?: number | null; - transit_time?: number | null; - radius?: number | null; - latitude?: number | null; - longitude?: number | null; - cities?: string[] | null; - postal_codes?: string[] | null; - country_codes?: string[] | null; -} - -// null -export interface UpdateServiceZoneMutationInput { - id: string; - service_id: string; - zone_index: number; - zone: UpdateServiceZoneInput; -} - -// null -export interface AccountFilter { - offset?: number | null; - first?: number | null; - id?: string | null; - name?: string | null; - slug?: string | null; - is_active?: boolean | null; - order_by?: string | null; -} - -// null -export interface CreateOrganizationAccountMutationInput { - name: string; - slug?: string | null; - is_active?: boolean | null; -} - -// null -export interface UpdateOrganizationAccountMutationInput { - id: string; - name?: string | null; - slug?: string | null; - is_active?: boolean | null; -} - -// null -export interface DisableOrganizationAccountMutationInput { - id: string; -} - -// null -export interface DeleteOrganizationAccountMutationInput { - id: string; -} - -// null -export interface PermissionGroupFilter { - offset?: number | null; - first?: number | null; -} - -//============================================================== -// END Enums and Input Objects -//============================================================== \ No newline at end of file +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL query operation: GetSystemConnections +// ==================================================== + +export interface GetSystemConnections_system_carrier_connections_edges_node { + id: string; + carrier_name: string; + carrier_id: string; + display_name: string; + test_mode: boolean; + active: boolean; + capabilities: string[]; + credentials: any; + config: any | null; + metadata: any | null; + object_type: string | null; +} + +export interface GetSystemConnections_system_carrier_connections_edges { + node: GetSystemConnections_system_carrier_connections_edges_node; + cursor: string; +} + +export interface GetSystemConnections_system_carrier_connections_page_info { + has_next_page: boolean; + has_previous_page: boolean; + start_cursor: string | null; + end_cursor: string | null; +} + +export interface GetSystemConnections_system_carrier_connections { + edges: GetSystemConnections_system_carrier_connections_edges[]; + page_info: GetSystemConnections_system_carrier_connections_page_info; +} + +export interface GetSystemConnections { + system_carrier_connections: GetSystemConnections_system_carrier_connections; +} + +export interface GetSystemConnectionsVariables { + filter?: CarrierFilter | null; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL query operation: GetSystemConnection +// ==================================================== + +export interface GetSystemConnection_system_carrier_connection { + id: string; + carrier_name: string; + carrier_id: string; + display_name: string; + test_mode: boolean; + active: boolean; + capabilities: string[]; + credentials: any; + config: any | null; + metadata: any | null; + object_type: string | null; +} + +export interface GetSystemConnection { + system_carrier_connection: GetSystemConnection_system_carrier_connection | null; +} + +export interface GetSystemConnectionVariables { + id: string; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: CreateSystemConnection +// ==================================================== + +export interface CreateSystemConnection_create_system_carrier_connection_errors { + field: string; + messages: string[]; +} + +export interface CreateSystemConnection_create_system_carrier_connection_connection { + id: string; + carrier_name: string; + carrier_id: string; + display_name: string; + test_mode: boolean; + active: boolean; + capabilities: string[]; + credentials: any; + config: any | null; + metadata: any | null; + object_type: string | null; +} + +export interface CreateSystemConnection_create_system_carrier_connection { + errors: CreateSystemConnection_create_system_carrier_connection_errors[] | null; + connection: CreateSystemConnection_create_system_carrier_connection_connection | null; +} + +export interface CreateSystemConnection { + create_system_carrier_connection: CreateSystemConnection_create_system_carrier_connection; +} + +export interface CreateSystemConnectionVariables { + data: CreateConnectionMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: UpdateSystemConnection +// ==================================================== + +export interface UpdateSystemConnection_update_system_carrier_connection_errors { + field: string; + messages: string[]; +} + +export interface UpdateSystemConnection_update_system_carrier_connection_connection { + id: string; + carrier_name: string; + carrier_id: string; + display_name: string; + test_mode: boolean; + active: boolean; + capabilities: string[]; + credentials: any; + config: any | null; + metadata: any | null; + object_type: string | null; +} + +export interface UpdateSystemConnection_update_system_carrier_connection { + errors: UpdateSystemConnection_update_system_carrier_connection_errors[] | null; + connection: UpdateSystemConnection_update_system_carrier_connection_connection | null; +} + +export interface UpdateSystemConnection { + update_system_carrier_connection: UpdateSystemConnection_update_system_carrier_connection; +} + +export interface UpdateSystemConnectionVariables { + data: UpdateConnectionMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: DeleteSystemConnection +// ==================================================== + +export interface DeleteSystemConnection_delete_system_carrier_connection_errors { + field: string; + messages: string[]; +} + +export interface DeleteSystemConnection_delete_system_carrier_connection { + errors: DeleteSystemConnection_delete_system_carrier_connection_errors[] | null; + id: string; +} + +export interface DeleteSystemConnection { + delete_system_carrier_connection: DeleteSystemConnection_delete_system_carrier_connection; +} + +export interface DeleteSystemConnectionVariables { + data: DeleteConnectionMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL query operation: GetMe +// ==================================================== + +export interface GetMe_me { + id: number; + email: string; + full_name: string; + is_staff: boolean; + is_active: boolean; + is_superuser: boolean | null; + last_login: any | null; + permissions: string[] | null; +} + +export interface GetMe { + me: GetMe_me; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL query operation: GetUser +// ==================================================== + +export interface GetUser_user { + id: number; + email: string; + full_name: string; + is_staff: boolean; + is_active: boolean; + is_superuser: boolean | null; + last_login: any | null; + permissions: string[] | null; +} + +export interface GetUser { + user: GetUser_user | null; +} + +export interface GetUserVariables { + email: string; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL query operation: GetUsers +// ==================================================== + +export interface GetUsers_users_edges_node { + id: number; + email: string; + full_name: string; + is_staff: boolean; + is_active: boolean; + is_superuser: boolean | null; + last_login: any | null; + permissions: string[] | null; +} + +export interface GetUsers_users_edges { + node: GetUsers_users_edges_node; + cursor: string; +} + +export interface GetUsers_users_page_info { + count: number; + has_next_page: boolean; + has_previous_page: boolean; + start_cursor: string | null; + end_cursor: string | null; +} + +export interface GetUsers_users { + edges: GetUsers_users_edges[]; + page_info: GetUsers_users_page_info; +} + +export interface GetUsers { + users: GetUsers_users; +} + +export interface GetUsersVariables { + filter?: UserFilter | null; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: CreateUser +// ==================================================== + +export interface CreateUser_create_user_user { + id: number; + email: string; + full_name: string; + is_staff: boolean; + is_active: boolean; + is_superuser: boolean | null; + last_login: any | null; + permissions: string[] | null; +} + +export interface CreateUser_create_user_errors { + field: string; + messages: string[]; +} + +export interface CreateUser_create_user { + user: CreateUser_create_user_user | null; + errors: CreateUser_create_user_errors[] | null; +} + +export interface CreateUser { + create_user: CreateUser_create_user; +} + +export interface CreateUserVariables { + data: CreateUserMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: UpdateUser +// ==================================================== + +export interface UpdateUser_update_user_user { + id: number; + email: string; + full_name: string; + is_staff: boolean; + is_active: boolean; + is_superuser: boolean | null; + last_login: any | null; + permissions: string[] | null; +} + +export interface UpdateUser_update_user_errors { + field: string; + messages: string[]; +} + +export interface UpdateUser_update_user { + user: UpdateUser_update_user_user | null; + errors: UpdateUser_update_user_errors[] | null; +} + +export interface UpdateUser { + update_user: UpdateUser_update_user; +} + +export interface UpdateUserVariables { + data: UpdateUserMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: RemoveUser +// ==================================================== + +export interface RemoveUser_remove_user_errors { + field: string; + messages: string[]; +} + +export interface RemoveUser_remove_user { + errors: RemoveUser_remove_user_errors[] | null; + id: number; +} + +export interface RemoveUser { + remove_user: RemoveUser_remove_user; +} + +export interface RemoveUserVariables { + data: DeleteUserMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL query operation: GetConfigs +// ==================================================== + +export interface GetConfigs_configs { + APP_NAME: string | null; + APP_WEBSITE: string | null; + EMAIL_USE_TLS: boolean | null; + EMAIL_HOST_USER: string | null; + EMAIL_HOST_PASSWORD: string | null; + EMAIL_HOST: string | null; + EMAIL_PORT: number | null; + EMAIL_FROM_ADDRESS: string | null; + GOOGLE_CLOUD_API_KEY: string | null; + CANADAPOST_ADDRESS_COMPLETE_API_KEY: string | null; + ORDER_DATA_RETENTION: number | null; + TRACKER_DATA_RETENTION: number | null; + SHIPMENT_DATA_RETENTION: number | null; + API_LOGS_DATA_RETENTION: number | null; + AUDIT_LOGGING: boolean | null; + ALLOW_SIGNUP: boolean | null; + ALLOW_ADMIN_APPROVED_SIGNUP: boolean | null; + ALLOW_MULTI_ACCOUNT: boolean | null; + ADMIN_DASHBOARD: boolean | null; + MULTI_ORGANIZATIONS: boolean | null; + ORDERS_MANAGEMENT: boolean | null; + APPS_MANAGEMENT: boolean | null; + DOCUMENTS_MANAGEMENT: boolean | null; + DATA_IMPORT_EXPORT: boolean | null; + WORKFLOW_MANAGEMENT: boolean | null; + PERSIST_SDK_TRACING: boolean | null; +} + +export interface GetConfigs { + configs: GetConfigs_configs; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: UpdateConfigs +// ==================================================== + +export interface UpdateConfigs_update_configs_errors { + field: string; + messages: string[]; +} + +export interface UpdateConfigs_update_configs_configs { + APP_NAME: string | null; + APP_WEBSITE: string | null; + EMAIL_USE_TLS: boolean | null; + EMAIL_HOST_USER: string | null; + EMAIL_HOST_PASSWORD: string | null; + EMAIL_HOST: string | null; + EMAIL_PORT: number | null; + EMAIL_FROM_ADDRESS: string | null; + GOOGLE_CLOUD_API_KEY: string | null; + CANADAPOST_ADDRESS_COMPLETE_API_KEY: string | null; + ORDER_DATA_RETENTION: number | null; + TRACKER_DATA_RETENTION: number | null; + SHIPMENT_DATA_RETENTION: number | null; + API_LOGS_DATA_RETENTION: number | null; + AUDIT_LOGGING: boolean | null; + ALLOW_SIGNUP: boolean | null; + ALLOW_ADMIN_APPROVED_SIGNUP: boolean | null; + ALLOW_MULTI_ACCOUNT: boolean | null; + ADMIN_DASHBOARD: boolean | null; + MULTI_ORGANIZATIONS: boolean | null; + ORDERS_MANAGEMENT: boolean | null; + APPS_MANAGEMENT: boolean | null; + DOCUMENTS_MANAGEMENT: boolean | null; + DATA_IMPORT_EXPORT: boolean | null; + WORKFLOW_MANAGEMENT: boolean | null; + PERSIST_SDK_TRACING: boolean | null; +} + +export interface UpdateConfigs_update_configs { + errors: UpdateConfigs_update_configs_errors[] | null; + configs: UpdateConfigs_update_configs_configs | null; +} + +export interface UpdateConfigs { + update_configs: UpdateConfigs_update_configs; +} + +export interface UpdateConfigsVariables { + data: InstanceConfigMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL query operation: GetSurcharge +// ==================================================== + +export interface GetSurcharge_surcharge_carrier_accounts { + id: string; + active: boolean; + carrier_id: string; +} + +export interface GetSurcharge_surcharge { + id: string; + name: string; + amount: number; + surcharge_type: string; + object_type: string; + active: boolean; + services: string[]; + carriers: string[]; + carrier_accounts: GetSurcharge_surcharge_carrier_accounts[]; +} + +export interface GetSurcharge { + surcharge: GetSurcharge_surcharge | null; +} + +export interface GetSurchargeVariables { + id: string; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL query operation: GetSurcharges +// ==================================================== + +export interface GetSurcharges_surcharges_edges_node_carrier_accounts { + id: string; + active: boolean; + carrier_id: string; +} + +export interface GetSurcharges_surcharges_edges_node { + id: string; + name: string; + amount: number; + surcharge_type: string; + object_type: string; + active: boolean; + services: string[]; + carriers: string[]; + carrier_accounts: GetSurcharges_surcharges_edges_node_carrier_accounts[]; +} + +export interface GetSurcharges_surcharges_edges { + node: GetSurcharges_surcharges_edges_node; + cursor: string; +} + +export interface GetSurcharges_surcharges_page_info { + count: number; + has_next_page: boolean; + has_previous_page: boolean; + start_cursor: string | null; + end_cursor: string | null; +} + +export interface GetSurcharges_surcharges { + edges: GetSurcharges_surcharges_edges[]; + page_info: GetSurcharges_surcharges_page_info; +} + +export interface GetSurcharges { + surcharges: GetSurcharges_surcharges; +} + +export interface GetSurchargesVariables { + filter?: SurchargeFilter | null; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: CreateSurcharge +// ==================================================== + +export interface CreateSurcharge_create_surcharge_errors { + field: string; + messages: string[]; +} + +export interface CreateSurcharge_create_surcharge_surcharge_carrier_accounts { + id: string; + active: boolean; + carrier_id: string; +} + +export interface CreateSurcharge_create_surcharge_surcharge { + id: string; + name: string; + amount: number; + surcharge_type: string; + object_type: string; + active: boolean; + services: string[]; + carriers: string[]; + carrier_accounts: CreateSurcharge_create_surcharge_surcharge_carrier_accounts[]; +} + +export interface CreateSurcharge_create_surcharge { + errors: CreateSurcharge_create_surcharge_errors[] | null; + surcharge: CreateSurcharge_create_surcharge_surcharge | null; +} + +export interface CreateSurcharge { + create_surcharge: CreateSurcharge_create_surcharge; +} + +export interface CreateSurchargeVariables { + data: CreateSurchargeMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: UpdateSurcharge +// ==================================================== + +export interface UpdateSurcharge_update_surcharge_errors { + field: string; + messages: string[]; +} + +export interface UpdateSurcharge_update_surcharge_surcharge_carrier_accounts { + id: string; + active: boolean; + carrier_id: string; +} + +export interface UpdateSurcharge_update_surcharge_surcharge { + id: string; + name: string; + amount: number; + surcharge_type: string; + object_type: string; + active: boolean; + services: string[]; + carriers: string[]; + carrier_accounts: UpdateSurcharge_update_surcharge_surcharge_carrier_accounts[]; +} + +export interface UpdateSurcharge_update_surcharge { + errors: UpdateSurcharge_update_surcharge_errors[] | null; + surcharge: UpdateSurcharge_update_surcharge_surcharge | null; +} + +export interface UpdateSurcharge { + update_surcharge: UpdateSurcharge_update_surcharge; +} + +export interface UpdateSurchargeVariables { + data: UpdateSurchargeMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: DeleteSurcharge +// ==================================================== + +export interface DeleteSurcharge_delete_surcharge_errors { + field: string; + messages: string[]; +} + +export interface DeleteSurcharge_delete_surcharge { + errors: DeleteSurcharge_delete_surcharge_errors[] | null; + id: string; +} + +export interface DeleteSurcharge { + delete_surcharge: DeleteSurcharge_delete_surcharge; +} + +export interface DeleteSurchargeVariables { + data: DeleteMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL query operation: GetRateSheet +// ==================================================== + +export interface GetRateSheet_rate_sheet_services_zones { + object_type: string; + label: string | null; + rate: number | null; + min_weight: number | null; + max_weight: number | null; + transit_days: number | null; + transit_time: number | null; + radius: number | null; + latitude: number | null; + longitude: number | null; + cities: string[] | null; + postal_codes: string[] | null; + country_codes: CountryCodeEnum[] | null; +} + +export interface GetRateSheet_rate_sheet_services { + id: string; + object_type: string; + service_name: string | null; + service_code: string | null; + carrier_service_code: string | null; + description: string | null; + active: boolean | null; + currency: CurrencyCodeEnum | null; + transit_days: number | null; + transit_time: number | null; + max_width: number | null; + max_height: number | null; + max_length: number | null; + dimension_unit: DimensionUnitEnum | null; + max_weight: number | null; + weight_unit: WeightUnitEnum | null; + domicile: boolean | null; + international: boolean | null; + metadata: any | null; + zones: GetRateSheet_rate_sheet_services_zones[]; +} + +export interface GetRateSheet_rate_sheet_carriers { + id: string; + carrier_id: string; + carrier_name: string; + display_name: string; + active: boolean; + is_system: boolean; + test_mode: boolean; + capabilities: string[]; +} + +export interface GetRateSheet_rate_sheet { + id: string; + name: string; + slug: string; + carrier_name: CarrierNameEnum; + object_type: string; + metadata: any | null; + services: GetRateSheet_rate_sheet_services[]; + carriers: GetRateSheet_rate_sheet_carriers[]; +} + +export interface GetRateSheet { + rate_sheet: GetRateSheet_rate_sheet | null; +} + +export interface GetRateSheetVariables { + id: string; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL query operation: GetRateSheets +// ==================================================== + +export interface GetRateSheets_rate_sheets_edges_node_services { + id: string; + service_name: string | null; + service_code: string | null; + carrier_service_code: string | null; + description: string | null; + active: boolean | null; +} + +export interface GetRateSheets_rate_sheets_edges_node_carriers { + id: string; + carrier_id: string; + carrier_name: string; + display_name: string; + active: boolean; + is_system: boolean; + test_mode: boolean; + capabilities: string[]; +} + +export interface GetRateSheets_rate_sheets_edges_node { + id: string; + name: string; + slug: string; + carrier_name: CarrierNameEnum; + object_type: string; + metadata: any | null; + services: GetRateSheets_rate_sheets_edges_node_services[]; + carriers: GetRateSheets_rate_sheets_edges_node_carriers[]; +} + +export interface GetRateSheets_rate_sheets_edges { + node: GetRateSheets_rate_sheets_edges_node; + cursor: string; +} + +export interface GetRateSheets_rate_sheets_page_info { + count: number; + has_next_page: boolean; + has_previous_page: boolean; + start_cursor: string | null; + end_cursor: string | null; +} + +export interface GetRateSheets_rate_sheets { + edges: GetRateSheets_rate_sheets_edges[]; + page_info: GetRateSheets_rate_sheets_page_info; +} + +export interface GetRateSheets { + rate_sheets: GetRateSheets_rate_sheets; +} + +export interface GetRateSheetsVariables { + filter?: RateSheetFilter | null; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: CreateRateSheet +// ==================================================== + +export interface CreateRateSheet_create_rate_sheet_errors { + field: string; + messages: string[]; +} + +export interface CreateRateSheet_create_rate_sheet_rate_sheet_services_zones { + label: string | null; + rate: number | null; + min_weight: number | null; + max_weight: number | null; + transit_days: number | null; + transit_time: number | null; + radius: number | null; + latitude: number | null; + longitude: number | null; + cities: string[] | null; + postal_codes: string[] | null; + country_codes: CountryCodeEnum[] | null; +} + +export interface CreateRateSheet_create_rate_sheet_rate_sheet_services { + id: string; + service_name: string | null; + service_code: string | null; + carrier_service_code: string | null; + description: string | null; + active: boolean | null; + metadata: any | null; + zones: CreateRateSheet_create_rate_sheet_rate_sheet_services_zones[]; +} + +export interface CreateRateSheet_create_rate_sheet_rate_sheet_carriers { + id: string; + carrier_id: string; + carrier_name: string; + display_name: string; + active: boolean; + is_system: boolean; + test_mode: boolean; + capabilities: string[]; +} + +export interface CreateRateSheet_create_rate_sheet_rate_sheet { + id: string; + name: string; + slug: string; + carrier_name: CarrierNameEnum; + object_type: string; + metadata: any | null; + services: CreateRateSheet_create_rate_sheet_rate_sheet_services[]; + carriers: CreateRateSheet_create_rate_sheet_rate_sheet_carriers[]; +} + +export interface CreateRateSheet_create_rate_sheet { + errors: CreateRateSheet_create_rate_sheet_errors[] | null; + rate_sheet: CreateRateSheet_create_rate_sheet_rate_sheet | null; +} + +export interface CreateRateSheet { + create_rate_sheet: CreateRateSheet_create_rate_sheet; +} + +export interface CreateRateSheetVariables { + data: CreateRateSheetMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: UpdateRateSheet +// ==================================================== + +export interface UpdateRateSheet_update_rate_sheet_errors { + field: string; + messages: string[]; +} + +export interface UpdateRateSheet_update_rate_sheet_rate_sheet_services_zones { + label: string | null; + rate: number | null; + min_weight: number | null; + max_weight: number | null; + transit_days: number | null; + transit_time: number | null; + radius: number | null; + latitude: number | null; + longitude: number | null; + cities: string[] | null; + postal_codes: string[] | null; + country_codes: CountryCodeEnum[] | null; +} + +export interface UpdateRateSheet_update_rate_sheet_rate_sheet_services { + id: string; + service_name: string | null; + service_code: string | null; + carrier_service_code: string | null; + description: string | null; + active: boolean | null; + metadata: any | null; + zones: UpdateRateSheet_update_rate_sheet_rate_sheet_services_zones[]; +} + +export interface UpdateRateSheet_update_rate_sheet_rate_sheet_carriers { + id: string; + carrier_id: string; + carrier_name: string; + display_name: string; + active: boolean; + is_system: boolean; + test_mode: boolean; + capabilities: string[]; +} + +export interface UpdateRateSheet_update_rate_sheet_rate_sheet { + id: string; + name: string; + slug: string; + carrier_name: CarrierNameEnum; + object_type: string; + metadata: any | null; + services: UpdateRateSheet_update_rate_sheet_rate_sheet_services[]; + carriers: UpdateRateSheet_update_rate_sheet_rate_sheet_carriers[]; +} + +export interface UpdateRateSheet_update_rate_sheet { + errors: UpdateRateSheet_update_rate_sheet_errors[] | null; + rate_sheet: UpdateRateSheet_update_rate_sheet_rate_sheet | null; +} + +export interface UpdateRateSheet { + update_rate_sheet: UpdateRateSheet_update_rate_sheet; +} + +export interface UpdateRateSheetVariables { + data: UpdateRateSheetMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: UpdateServiceZone +// ==================================================== + +export interface UpdateServiceZone_update_service_zone_errors { + field: string; + messages: string[]; +} + +export interface UpdateServiceZone_update_service_zone_rate_sheet_services_zones { + label: string | null; + rate: number | null; + min_weight: number | null; + max_weight: number | null; + transit_days: number | null; + transit_time: number | null; + radius: number | null; + latitude: number | null; + longitude: number | null; + cities: string[] | null; + postal_codes: string[] | null; + country_codes: CountryCodeEnum[] | null; +} + +export interface UpdateServiceZone_update_service_zone_rate_sheet_services { + id: string; + zones: UpdateServiceZone_update_service_zone_rate_sheet_services_zones[]; +} + +export interface UpdateServiceZone_update_service_zone_rate_sheet { + id: string; + services: UpdateServiceZone_update_service_zone_rate_sheet_services[]; +} + +export interface UpdateServiceZone_update_service_zone { + errors: UpdateServiceZone_update_service_zone_errors[] | null; + rate_sheet: UpdateServiceZone_update_service_zone_rate_sheet | null; +} + +export interface UpdateServiceZone { + update_service_zone: UpdateServiceZone_update_service_zone; +} + +export interface UpdateServiceZoneVariables { + data: UpdateServiceZoneMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: DeleteRateSheet +// ==================================================== + +export interface DeleteRateSheet_delete_rate_sheet_errors { + field: string; + messages: string[]; +} + +export interface DeleteRateSheet_delete_rate_sheet { + errors: DeleteRateSheet_delete_rate_sheet_errors[] | null; + id: string; +} + +export interface DeleteRateSheet { + delete_rate_sheet: DeleteRateSheet_delete_rate_sheet; +} + +export interface DeleteRateSheetVariables { + data: DeleteMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL query operation: GetAccounts +// ==================================================== + +export interface GetAccounts_accounts_edges_node_usage { + members: number | null; + total_errors: number | null; + order_volume: number | null; + total_requests: number | null; + total_trackers: number | null; + total_shipments: number | null; + unfulfilled_orders: number | null; + total_shipping_spend: number | null; +} + +export interface GetAccounts_accounts_edges_node { + id: string; + name: string; + slug: string; + is_active: boolean; + created: any; + modified: any; + usage: GetAccounts_accounts_edges_node_usage; +} + +export interface GetAccounts_accounts_edges { + node: GetAccounts_accounts_edges_node; + cursor: string; +} + +export interface GetAccounts_accounts_page_info { + count: number; + has_next_page: boolean; + has_previous_page: boolean; + start_cursor: string | null; + end_cursor: string | null; +} + +export interface GetAccounts_accounts { + edges: GetAccounts_accounts_edges[]; + page_info: GetAccounts_accounts_page_info; +} + +export interface GetAccounts { + accounts: GetAccounts_accounts; +} + +export interface GetAccountsVariables { + filter?: AccountFilter | null; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: CreateOrganizationAccount +// ==================================================== + +export interface CreateOrganizationAccount_create_organization_account_account { + id: string; +} + +export interface CreateOrganizationAccount_create_organization_account_errors { + field: string; + messages: string[]; +} + +export interface CreateOrganizationAccount_create_organization_account { + account: CreateOrganizationAccount_create_organization_account_account | null; + errors: CreateOrganizationAccount_create_organization_account_errors[] | null; +} + +export interface CreateOrganizationAccount { + create_organization_account: CreateOrganizationAccount_create_organization_account; +} + +export interface CreateOrganizationAccountVariables { + data: CreateOrganizationAccountMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: UpdateOrganizationAccount +// ==================================================== + +export interface UpdateOrganizationAccount_update_organization_account_account { + id: string; +} + +export interface UpdateOrganizationAccount_update_organization_account_errors { + field: string; + messages: string[]; +} + +export interface UpdateOrganizationAccount_update_organization_account { + account: UpdateOrganizationAccount_update_organization_account_account | null; + errors: UpdateOrganizationAccount_update_organization_account_errors[] | null; +} + +export interface UpdateOrganizationAccount { + update_organization_account: UpdateOrganizationAccount_update_organization_account; +} + +export interface UpdateOrganizationAccountVariables { + data: UpdateOrganizationAccountMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: DisableOrganizationAccount +// ==================================================== + +export interface DisableOrganizationAccount_disable_organization_account_account { + id: string; +} + +export interface DisableOrganizationAccount_disable_organization_account_errors { + field: string; + messages: string[]; +} + +export interface DisableOrganizationAccount_disable_organization_account { + account: DisableOrganizationAccount_disable_organization_account_account | null; + errors: DisableOrganizationAccount_disable_organization_account_errors[] | null; +} + +export interface DisableOrganizationAccount { + disable_organization_account: DisableOrganizationAccount_disable_organization_account; +} + +export interface DisableOrganizationAccountVariables { + data: DisableOrganizationAccountMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: DeleteOrganizationAccount +// ==================================================== + +export interface DeleteOrganizationAccount_delete_organization_account_account { + id: string; +} + +export interface DeleteOrganizationAccount_delete_organization_account_errors { + field: string; + messages: string[]; +} + +export interface DeleteOrganizationAccount_delete_organization_account { + account: DeleteOrganizationAccount_delete_organization_account_account | null; + errors: DeleteOrganizationAccount_delete_organization_account_errors[] | null; +} + +export interface DeleteOrganizationAccount { + delete_organization_account: DeleteOrganizationAccount_delete_organization_account; +} + +export interface DeleteOrganizationAccountVariables { + data: DeleteOrganizationAccountMutationInput; +} + + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL query operation: GetPermissionGroups +// ==================================================== + +export interface GetPermissionGroups_permission_groups_edges_node { + id: number; + name: string; + permissions: string[] | null; +} + +export interface GetPermissionGroups_permission_groups_edges { + node: GetPermissionGroups_permission_groups_edges_node; + cursor: string; +} + +export interface GetPermissionGroups_permission_groups_page_info { + count: number; + has_next_page: boolean; + has_previous_page: boolean; + start_cursor: string | null; + end_cursor: string | null; +} + +export interface GetPermissionGroups_permission_groups { + edges: GetPermissionGroups_permission_groups_edges[]; + page_info: GetPermissionGroups_permission_groups_page_info; +} + +export interface GetPermissionGroups { + permission_groups: GetPermissionGroups_permission_groups; +} + +export interface GetPermissionGroupsVariables { + filter?: PermissionGroupFilter | null; +} + +/* tslint:disable */ +// This file was automatically generated and should not be edited. + +//============================================================== +// START Enums and Input Objects +//============================================================== + +export enum CarrierNameEnum { + allied_express = "allied_express", + allied_express_local = "allied_express_local", + amazon_shipping = "amazon_shipping", + aramex = "aramex", + asendia_us = "asendia_us", + australiapost = "australiapost", + boxknight = "boxknight", + bpost = "bpost", + canadapost = "canadapost", + canpar = "canpar", + chronopost = "chronopost", + colissimo = "colissimo", + dhl_express = "dhl_express", + dhl_parcel_de = "dhl_parcel_de", + dhl_poland = "dhl_poland", + dhl_universal = "dhl_universal", + dicom = "dicom", + dpd = "dpd", + dpdhl = "dpdhl", + easypost = "easypost", + easyship = "easyship", + eshipper = "eshipper", + fedex = "fedex", + fedex_ws = "fedex_ws", + freightcom = "freightcom", + generic = "generic", + geodis = "geodis", + hay_post = "hay_post", + laposte = "laposte", + locate2u = "locate2u", + nationex = "nationex", + purolator = "purolator", + roadie = "roadie", + royalmail = "royalmail", + sapient = "sapient", + seko = "seko", + sendle = "sendle", + tge = "tge", + tnt = "tnt", + ups = "ups", + usps = "usps", + usps_international = "usps_international", + usps_wt = "usps_wt", + usps_wt_international = "usps_wt_international", + zoom2u = "zoom2u", +} + +export enum SurchargeTypeEnum { + AMOUNT = "AMOUNT", + PERCENTAGE = "PERCENTAGE", +} + +export enum CurrencyCodeEnum { + AED = "AED", + AMD = "AMD", + ANG = "ANG", + AOA = "AOA", + ARS = "ARS", + AUD = "AUD", + AWG = "AWG", + AZN = "AZN", + BAM = "BAM", + BBD = "BBD", + BDT = "BDT", + BGN = "BGN", + BHD = "BHD", + BIF = "BIF", + BMD = "BMD", + BND = "BND", + BOB = "BOB", + BRL = "BRL", + BSD = "BSD", + BTN = "BTN", + BWP = "BWP", + BYN = "BYN", + BZD = "BZD", + CAD = "CAD", + CDF = "CDF", + CHF = "CHF", + CLP = "CLP", + CNY = "CNY", + COP = "COP", + CRC = "CRC", + CUC = "CUC", + CVE = "CVE", + CZK = "CZK", + DJF = "DJF", + DKK = "DKK", + DOP = "DOP", + DZD = "DZD", + EGP = "EGP", + ERN = "ERN", + ETB = "ETB", + EUR = "EUR", + FJD = "FJD", + GBP = "GBP", + GEL = "GEL", + GHS = "GHS", + GMD = "GMD", + GNF = "GNF", + GTQ = "GTQ", + GYD = "GYD", + HKD = "HKD", + HNL = "HNL", + HRK = "HRK", + HTG = "HTG", + HUF = "HUF", + IDR = "IDR", + ILS = "ILS", + INR = "INR", + IRR = "IRR", + ISK = "ISK", + JMD = "JMD", + JOD = "JOD", + JPY = "JPY", + KES = "KES", + KGS = "KGS", + KHR = "KHR", + KMF = "KMF", + KPW = "KPW", + KRW = "KRW", + KWD = "KWD", + KYD = "KYD", + KZT = "KZT", + LAK = "LAK", + LKR = "LKR", + LRD = "LRD", + LSL = "LSL", + LYD = "LYD", + MAD = "MAD", + MDL = "MDL", + MGA = "MGA", + MKD = "MKD", + MMK = "MMK", + MNT = "MNT", + MOP = "MOP", + MRO = "MRO", + MUR = "MUR", + MVR = "MVR", + MWK = "MWK", + MXN = "MXN", + MYR = "MYR", + MZN = "MZN", + NAD = "NAD", + NGN = "NGN", + NIO = "NIO", + NOK = "NOK", + NPR = "NPR", + NZD = "NZD", + OMR = "OMR", + PEN = "PEN", + PGK = "PGK", + PHP = "PHP", + PKR = "PKR", + PLN = "PLN", + PYG = "PYG", + QAR = "QAR", + RSD = "RSD", + RUB = "RUB", + RWF = "RWF", + SAR = "SAR", + SBD = "SBD", + SCR = "SCR", + SDG = "SDG", + SEK = "SEK", + SGD = "SGD", + SHP = "SHP", + SLL = "SLL", + SOS = "SOS", + SRD = "SRD", + SSP = "SSP", + STD = "STD", + SYP = "SYP", + SZL = "SZL", + THB = "THB", + TJS = "TJS", + TND = "TND", + TOP = "TOP", + TRY = "TRY", + TTD = "TTD", + TWD = "TWD", + TZS = "TZS", + UAH = "UAH", + USD = "USD", + UYU = "UYU", + UZS = "UZS", + VEF = "VEF", + VND = "VND", + VUV = "VUV", + WST = "WST", + XAF = "XAF", + XCD = "XCD", + XOF = "XOF", + XPF = "XPF", + YER = "YER", + ZAR = "ZAR", +} + +export enum DimensionUnitEnum { + CM = "CM", + IN = "IN", +} + +export enum WeightUnitEnum { + G = "G", + KG = "KG", + LB = "LB", + OZ = "OZ", +} + +export enum CountryCodeEnum { + AC = "AC", + AD = "AD", + AE = "AE", + AF = "AF", + AG = "AG", + AI = "AI", + AL = "AL", + AM = "AM", + AN = "AN", + AO = "AO", + AR = "AR", + AS = "AS", + AT = "AT", + AU = "AU", + AW = "AW", + AZ = "AZ", + BA = "BA", + BB = "BB", + BD = "BD", + BE = "BE", + BF = "BF", + BG = "BG", + BH = "BH", + BI = "BI", + BJ = "BJ", + BL = "BL", + BM = "BM", + BN = "BN", + BO = "BO", + BR = "BR", + BS = "BS", + BT = "BT", + BW = "BW", + BY = "BY", + BZ = "BZ", + CA = "CA", + CD = "CD", + CF = "CF", + CG = "CG", + CH = "CH", + CI = "CI", + CK = "CK", + CL = "CL", + CM = "CM", + CN = "CN", + CO = "CO", + CR = "CR", + CU = "CU", + CV = "CV", + CY = "CY", + CZ = "CZ", + DE = "DE", + DJ = "DJ", + DK = "DK", + DM = "DM", + DO = "DO", + DZ = "DZ", + EC = "EC", + EE = "EE", + EG = "EG", + EH = "EH", + ER = "ER", + ES = "ES", + ET = "ET", + FI = "FI", + FJ = "FJ", + FK = "FK", + FM = "FM", + FO = "FO", + FR = "FR", + GA = "GA", + GB = "GB", + GD = "GD", + GE = "GE", + GF = "GF", + GG = "GG", + GH = "GH", + GI = "GI", + GL = "GL", + GM = "GM", + GN = "GN", + GP = "GP", + GQ = "GQ", + GR = "GR", + GT = "GT", + GU = "GU", + GW = "GW", + GY = "GY", + HK = "HK", + HN = "HN", + HR = "HR", + HT = "HT", + HU = "HU", + IC = "IC", + ID = "ID", + IE = "IE", + IL = "IL", + IM = "IM", + IN = "IN", + IQ = "IQ", + IR = "IR", + IS = "IS", + IT = "IT", + JE = "JE", + JM = "JM", + JO = "JO", + JP = "JP", + KE = "KE", + KG = "KG", + KH = "KH", + KI = "KI", + KM = "KM", + KN = "KN", + KP = "KP", + KR = "KR", + KV = "KV", + KW = "KW", + KY = "KY", + KZ = "KZ", + LA = "LA", + LB = "LB", + LC = "LC", + LI = "LI", + LK = "LK", + LR = "LR", + LS = "LS", + LT = "LT", + LU = "LU", + LV = "LV", + LY = "LY", + MA = "MA", + MC = "MC", + MD = "MD", + ME = "ME", + MF = "MF", + MG = "MG", + MH = "MH", + MK = "MK", + ML = "ML", + MM = "MM", + MN = "MN", + MO = "MO", + MP = "MP", + MQ = "MQ", + MR = "MR", + MS = "MS", + MT = "MT", + MU = "MU", + MV = "MV", + MW = "MW", + MX = "MX", + MY = "MY", + MZ = "MZ", + NA = "NA", + NC = "NC", + NE = "NE", + NG = "NG", + NI = "NI", + NL = "NL", + NO = "NO", + NP = "NP", + NR = "NR", + NU = "NU", + NZ = "NZ", + OM = "OM", + PA = "PA", + PE = "PE", + PF = "PF", + PG = "PG", + PH = "PH", + PK = "PK", + PL = "PL", + PR = "PR", + PT = "PT", + PW = "PW", + PY = "PY", + QA = "QA", + RE = "RE", + RO = "RO", + RS = "RS", + RU = "RU", + RW = "RW", + SA = "SA", + SB = "SB", + SC = "SC", + SD = "SD", + SE = "SE", + SG = "SG", + SH = "SH", + SI = "SI", + SK = "SK", + SL = "SL", + SM = "SM", + SN = "SN", + SO = "SO", + SR = "SR", + SS = "SS", + ST = "ST", + SV = "SV", + SX = "SX", + SY = "SY", + SZ = "SZ", + TC = "TC", + TD = "TD", + TG = "TG", + TH = "TH", + TJ = "TJ", + TL = "TL", + TN = "TN", + TO = "TO", + TR = "TR", + TT = "TT", + TV = "TV", + TW = "TW", + TZ = "TZ", + UA = "UA", + UG = "UG", + US = "US", + UY = "UY", + UZ = "UZ", + VA = "VA", + VC = "VC", + VE = "VE", + VG = "VG", + VI = "VI", + VN = "VN", + VU = "VU", + WS = "WS", + XB = "XB", + XC = "XC", + XE = "XE", + XM = "XM", + XN = "XN", + XS = "XS", + XY = "XY", + YE = "YE", + YT = "YT", + ZA = "ZA", + ZM = "ZM", + ZW = "ZW", +} + +// null +export interface CarrierFilter { + offset?: number | null; + first?: number | null; + after?: string | null; + before?: string | null; + active?: boolean | null; + metadata_key?: string | null; + metadata_value?: string | null; + carrier_name?: string[] | null; + order_by?: string | null; +} + +// null +export interface CreateConnectionMutationInput { + carrier_name: CarrierNameEnum; + carrier_id: string; + credentials: any; + active?: boolean | null; + config?: any | null; + metadata?: any | null; + capabilities?: string[] | null; +} + +// null +export interface UpdateConnectionMutationInput { + id: string; + active?: boolean | null; + carrier_id?: string | null; + credentials?: any | null; + config?: any | null; + metadata?: any | null; + capabilities?: string[] | null; +} + +// null +export interface DeleteConnectionMutationInput { + id: string; +} + +// null +export interface UserFilter { + offset?: number | null; + first?: number | null; + id?: string | null; + email?: string | null; + is_staff?: boolean | null; + is_active?: boolean | null; + is_superuser?: boolean | null; + order_by?: string | null; +} + +// null +export interface CreateUserMutationInput { + email: string; + password1: string; + password2: string; + redirect_url: string; + full_name?: string | null; + is_staff?: boolean | null; + is_active?: boolean | null; + is_superuser?: boolean | null; + organization_id?: string | null; + permissions?: string[] | null; +} + +// null +export interface UpdateUserMutationInput { + id: number; + email?: string | null; + full_name?: string | null; + is_staff?: boolean | null; + is_active?: boolean | null; + is_superuser?: boolean | null; + permissions?: string[] | null; +} + +// null +export interface DeleteUserMutationInput { + id: number; +} + +// null +export interface InstanceConfigMutationInput { + APP_NAME?: string | null; + APP_WEBSITE?: string | null; + EMAIL_USE_TLS?: boolean | null; + EMAIL_HOST_USER?: string | null; + EMAIL_HOST_PASSWORD?: string | null; + EMAIL_HOST?: string | null; + EMAIL_PORT?: number | null; + EMAIL_FROM_ADDRESS?: string | null; + GOOGLE_CLOUD_API_KEY?: string | null; + CANADAPOST_ADDRESS_COMPLETE_API_KEY?: string | null; + ORDER_DATA_RETENTION?: number | null; + TRACKER_DATA_RETENTION?: number | null; + SHIPMENT_DATA_RETENTION?: number | null; + API_LOGS_DATA_RETENTION?: number | null; + AUDIT_LOGGING?: boolean | null; + ALLOW_SIGNUP?: boolean | null; + ALLOW_ADMIN_APPROVED_SIGNUP?: boolean | null; + ALLOW_MULTI_ACCOUNT?: boolean | null; + ADMIN_DASHBOARD?: boolean | null; + MULTI_ORGANIZATIONS?: boolean | null; + ORDERS_MANAGEMENT?: boolean | null; + APPS_MANAGEMENT?: boolean | null; + DOCUMENTS_MANAGEMENT?: boolean | null; + DATA_IMPORT_EXPORT?: boolean | null; + WORKFLOW_MANAGEMENT?: boolean | null; + PERSIST_SDK_TRACING?: boolean | null; +} + +// null +export interface SurchargeFilter { + offset?: number | null; + first?: number | null; + id?: string | null; + name?: string | null; + active?: boolean | null; + surcharge_type?: SurchargeTypeEnum | null; +} + +// null +export interface CreateSurchargeMutationInput { + name: string; + amount: number; + surcharge_type: SurchargeTypeEnum; + active?: boolean | null; + carriers?: string[] | null; + services?: string[] | null; + organizations?: string[] | null; + carrier_accounts?: string[] | null; +} + +// null +export interface UpdateSurchargeMutationInput { + name?: string | null; + amount?: number | null; + surcharge_type?: SurchargeTypeEnum | null; + active?: boolean | null; + carriers?: string[] | null; + services?: string[] | null; + organizations?: string[] | null; + carrier_accounts?: string[] | null; + id: string; +} + +// null +export interface DeleteMutationInput { + id: string; +} + +// null +export interface RateSheetFilter { + offset?: number | null; + first?: number | null; + keyword?: string | null; +} + +// null +export interface CreateRateSheetMutationInput { + name: string; + carrier_name: CarrierNameEnum; + services?: CreateServiceLevelInput[] | null; + carriers?: string[] | null; + metadata?: any | null; +} + +// null +export interface CreateServiceLevelInput { + service_name: string; + service_code: string; + currency: CurrencyCodeEnum; + zones: ServiceZoneInput[]; + carrier_service_code?: string | null; + description?: string | null; + active?: boolean | null; + transit_days?: number | null; + transit_time?: number | null; + max_width?: number | null; + max_height?: number | null; + max_length?: number | null; + dimension_unit?: DimensionUnitEnum | null; + min_weight?: number | null; + max_weight?: number | null; + weight_unit?: WeightUnitEnum | null; + domicile?: boolean | null; + international?: boolean | null; + metadata?: any | null; +} + +// null +export interface ServiceZoneInput { + rate: number; + label?: string | null; + min_weight?: number | null; + max_weight?: number | null; + transit_days?: number | null; + transit_time?: number | null; + radius?: number | null; + latitude?: number | null; + longitude?: number | null; + cities?: string[] | null; + postal_codes?: string[] | null; + country_codes?: string[] | null; +} + +// null +export interface UpdateRateSheetMutationInput { + id: string; + name?: string | null; + services?: UpdateServiceLevelInput[] | null; + carriers?: string[] | null; + remove_missing_services?: boolean | null; + metadata?: any | null; +} + +// null +export interface UpdateServiceLevelInput { + service_name?: string | null; + service_code?: string | null; + currency?: CurrencyCodeEnum | null; + zones?: UpdateServiceZoneInput[] | null; + carrier_service_code?: string | null; + description?: string | null; + active?: boolean | null; + transit_days?: number | null; + transit_time?: number | null; + max_width?: number | null; + max_height?: number | null; + max_length?: number | null; + dimension_unit?: DimensionUnitEnum | null; + min_weight?: number | null; + max_weight?: number | null; + weight_unit?: WeightUnitEnum | null; + domicile?: boolean | null; + international?: boolean | null; + metadata?: any | null; + id?: string | null; +} + +// null +export interface UpdateServiceZoneInput { + rate?: number | null; + label?: string | null; + min_weight?: number | null; + max_weight?: number | null; + transit_days?: number | null; + transit_time?: number | null; + radius?: number | null; + latitude?: number | null; + longitude?: number | null; + cities?: string[] | null; + postal_codes?: string[] | null; + country_codes?: string[] | null; +} + +// null +export interface UpdateServiceZoneMutationInput { + id: string; + service_id: string; + zone_index: number; + zone: UpdateServiceZoneInput; +} + +// null +export interface AccountFilter { + offset?: number | null; + first?: number | null; + id?: string | null; + name?: string | null; + slug?: string | null; + is_active?: boolean | null; + order_by?: string | null; +} + +// null +export interface CreateOrganizationAccountMutationInput { + name: string; + slug?: string | null; + is_active?: boolean | null; +} + +// null +export interface UpdateOrganizationAccountMutationInput { + id: string; + name?: string | null; + slug?: string | null; + is_active?: boolean | null; +} + +// null +export interface DisableOrganizationAccountMutationInput { + id: string; +} + +// null +export interface DeleteOrganizationAccountMutationInput { + id: string; +} + +// null +export interface PermissionGroupFilter { + offset?: number | null; + first?: number | null; +} + +//============================================================== +// END Enums and Input Objects +//============================================================== diff --git a/schemas/graphql-admin.json b/schemas/graphql-admin.json index 2d31fee15..1c1645f9c 100644 --- a/schemas/graphql-admin.json +++ b/schemas/graphql-admin.json @@ -851,6 +851,30 @@ "name": "InstanceConfigType", "description": null, "fields": [ + { + "name": "APP_NAME", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "APP_WEBSITE", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "EMAIL_USE_TLS", "description": null, @@ -994,6 +1018,150 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "AUDIT_LOGGING", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ALLOW_SIGNUP", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ALLOW_ADMIN_APPROVED_SIGNUP", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ALLOW_MULTI_ACCOUNT", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ADMIN_DASHBOARD", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MULTI_ORGANIZATIONS", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ORDERS_MANAGEMENT", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "APPS_MANAGEMENT", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DOCUMENTS_MANAGEMENT", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DATA_IMPORT_EXPORT", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "WORKFLOW_MANAGEMENT", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PERSIST_SDK_TRACING", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -5263,6 +5431,26 @@ "description": null, "fields": null, "inputFields": [ + { + "name": "offset", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, { "name": "active", "description": null, @@ -7573,6 +7761,26 @@ "description": null, "fields": null, "inputFields": [ + { + "name": "APP_NAME", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "APP_WEBSITE", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, { "name": "EMAIL_USE_TLS", "description": null, @@ -7692,6 +7900,126 @@ "ofType": null }, "defaultValue": null + }, + { + "name": "AUDIT_LOGGING", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "ALLOW_SIGNUP", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "ALLOW_ADMIN_APPROVED_SIGNUP", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "ALLOW_MULTI_ACCOUNT", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "ADMIN_DASHBOARD", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "MULTI_ORGANIZATIONS", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "ORDERS_MANAGEMENT", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "APPS_MANAGEMENT", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "DOCUMENTS_MANAGEMENT", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "DATA_IMPORT_EXPORT", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "WORKFLOW_MANAGEMENT", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "PERSIST_SDK_TRACING", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null } ], "interfaces": null,