Refactor integration services and update import paths to align with the new domain structure, enhancing type safety and maintainability. Streamline Freebit integration by utilizing updated provider methods and removing deprecated types. Improve organization and consistency in data handling across various modules, including catalog and billing services.
This commit is contained in:
parent
69aa47ad59
commit
12c3dc976f
@ -1,4 +1,4 @@
|
||||
import type { SalesforceProductFieldMap } from "@customer-portal/domain";
|
||||
import type { SalesforceProductFieldMap } from "@customer-portal/domain/billing";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { ConfigService } from "@nestjs/config";
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import type {
|
||||
FreebitConfig,
|
||||
FreebitAuthRequest,
|
||||
FreebitAuthResponse,
|
||||
} from "../interfaces/freebit.types";
|
||||
} from "@customer-portal/domain/sim/providers/freebit";
|
||||
import { FreebitError } from "./freebit-error.service";
|
||||
|
||||
@Injectable()
|
||||
|
||||
@ -26,7 +26,6 @@ import type {
|
||||
FreebitAccountDetailsRequest,
|
||||
FreebitTrafficInfoRequest,
|
||||
FreebitQuotaHistoryRequest,
|
||||
FreebitQuotaHistoryResponse,
|
||||
FreebitEsimAddAccountRequest,
|
||||
} from "@customer-portal/domain/sim/providers/freebit";
|
||||
import type { SimDetails, SimTopUpHistory, SimUsage } from "@customer-portal/domain/sim";
|
||||
@ -200,7 +199,7 @@ export class FreebitOperationsService {
|
||||
|
||||
const response = await this.client.makeAuthenticatedRequest<
|
||||
FreebitQuotaHistoryResponse,
|
||||
typeof request
|
||||
FreebitQuotaHistoryRequest
|
||||
>("/mvno/getQuotaHistory/", request);
|
||||
|
||||
return this.mapper.mapToSimTopUpHistory(response, account);
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
type AccountData,
|
||||
type UpsertResult,
|
||||
} from "./services/salesforce-account.service";
|
||||
import type { SalesforceAccountRecord, SalesforceOrderRecord } from "@customer-portal/domain";
|
||||
import type { SalesforceAccountRecord, SalesforceOrderRecord } from "@customer-portal/domain/billing";
|
||||
|
||||
/**
|
||||
* Clean Salesforce Service - Only includes actually used functionality
|
||||
|
||||
@ -2,7 +2,7 @@ import { Injectable, Inject } from "@nestjs/common";
|
||||
import { Logger } from "nestjs-pino";
|
||||
import { getErrorMessage } from "@bff/core/utils/error.util";
|
||||
import { SalesforceConnection } from "./salesforce-connection.service";
|
||||
import type { SalesforceAccountRecord, SalesforceQueryResult } from "@customer-portal/domain";
|
||||
import type { SalesforceAccountRecord, SalesforceQueryResult } from "@customer-portal/domain/billing";
|
||||
|
||||
export interface AccountData {
|
||||
name: string;
|
||||
|
||||
@ -6,7 +6,7 @@ import type {
|
||||
SimCatalogProduct,
|
||||
SimActivationFeeCatalogItem,
|
||||
VpnCatalogProduct,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import { InternetCatalogService } from "./services/internet-catalog.service";
|
||||
import { SimCatalogService } from "./services/sim-catalog.service";
|
||||
import { VpnCatalogService } from "./services/vpn-catalog.service";
|
||||
|
||||
@ -12,7 +12,7 @@ import type {
|
||||
SalesforceProduct2WithPricebookEntries,
|
||||
SalesforcePricebookEntryRecord,
|
||||
SalesforceQueryResult,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
|
||||
@Injectable()
|
||||
export class BaseCatalogService {
|
||||
|
||||
@ -6,7 +6,7 @@ import type {
|
||||
InternetPlanCatalogItem,
|
||||
InternetInstallationCatalogItem,
|
||||
InternetAddonCatalogItem,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import { MappingsService } from "@bff/modules/id-mappings/mappings.service";
|
||||
import { SalesforceConnection } from "@bff/integrations/salesforce/services/salesforce-connection.service";
|
||||
import { SalesforceFieldMapService } from "@bff/core/config/field-map";
|
||||
|
||||
@ -6,7 +6,7 @@ import type {
|
||||
SalesforceProduct2WithPricebookEntries,
|
||||
SimCatalogProduct,
|
||||
SimActivationFeeCatalogItem,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import {
|
||||
mapSimProduct,
|
||||
mapSimActivationFee,
|
||||
|
||||
@ -7,7 +7,7 @@ import { BaseCatalogService } from "./base-catalog.service";
|
||||
import type {
|
||||
SalesforceProduct2WithPricebookEntries,
|
||||
VpnCatalogProduct,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import { mapVpnProduct } from "@bff/modules/catalog/utils/salesforce-product.mapper";
|
||||
|
||||
@Injectable()
|
||||
|
||||
@ -7,11 +7,11 @@ import type {
|
||||
SimActivationFeeCatalogItem,
|
||||
SimCatalogProduct,
|
||||
VpnCatalogProduct,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import type {
|
||||
SalesforceProduct2WithPricebookEntries,
|
||||
SalesforcePricebookEntryRecord,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import type { SalesforceFieldMap } from "@bff/core/config/field-map";
|
||||
|
||||
export type SalesforceCatalogProductRecord = SalesforceProduct2WithPricebookEntries;
|
||||
|
||||
@ -25,8 +25,8 @@ import type {
|
||||
PaymentGatewayList,
|
||||
InvoicePaymentLink,
|
||||
InvoiceListQuery,
|
||||
} from "@customer-portal/domain";
|
||||
import { invoiceListQuerySchema } from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import { invoiceListQuerySchema } from "@customer-portal/domain/billing";
|
||||
|
||||
interface AuthenticatedRequest {
|
||||
user: { id: string };
|
||||
|
||||
@ -5,7 +5,7 @@ import {
|
||||
Inject,
|
||||
} from "@nestjs/common";
|
||||
import { Logger } from "nestjs-pino";
|
||||
import { Invoice, InvoiceList } from "@customer-portal/domain";
|
||||
import { Invoice, InvoiceList } from "@customer-portal/domain/billing";
|
||||
import { WhmcsService } from "@bff/integrations/whmcs/whmcs.service";
|
||||
import { MappingsService } from "@bff/modules/id-mappings/mappings.service";
|
||||
import { getErrorMessage } from "@bff/core/utils/error.util";
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Injectable, Inject } from "@nestjs/common";
|
||||
import { Logger } from "nestjs-pino";
|
||||
import { Invoice, InvoiceList } from "@customer-portal/domain";
|
||||
import { Invoice, InvoiceList } from "@customer-portal/domain/billing";
|
||||
import { InvoiceRetrievalService } from "./invoice-retrieval.service";
|
||||
import { InvoiceHealthService } from "./invoice-health.service";
|
||||
import { InvoiceValidatorService } from "../validators/invoice-validator.service";
|
||||
|
||||
@ -15,7 +15,7 @@ import {
|
||||
updateAddressRequestSchema,
|
||||
type UpdateProfileRequest,
|
||||
type UpdateAddressRequest,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import type { RequestWithUser } from "@bff/modules/auth/auth.types";
|
||||
|
||||
@Controller("me")
|
||||
|
||||
@ -8,7 +8,7 @@ import { accountService } from "@/features/account/services/account.service";
|
||||
import { Sidebar } from "./Sidebar";
|
||||
import { Header } from "./Header";
|
||||
import { computeNavigation } from "./navigation";
|
||||
import type { Subscription } from "@customer-portal/domain";
|
||||
import type { Subscription } from "@customer-portal/domain/billing";
|
||||
|
||||
interface AppShellProps {
|
||||
children: React.ReactNode;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { Subscription } from "@customer-portal/domain";
|
||||
import type { Subscription } from "@customer-portal/domain/billing";
|
||||
import type { ReactNode } from "react";
|
||||
import {
|
||||
HomeIcon,
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
import { SubCard } from "@/components/molecules/SubCard/SubCard";
|
||||
import { MapPinIcon, PencilIcon, CheckIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
||||
import { AddressForm, type AddressFormProps } from "@/features/catalog/components";
|
||||
import type { Address } from "@customer-portal/domain";
|
||||
import type { Address } from "@customer-portal/domain/billing";
|
||||
|
||||
interface AddressCardProps {
|
||||
address: Address;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
import { SubCard } from "@/components/molecules/SubCard/SubCard";
|
||||
import { UserIcon, PencilIcon, CheckIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
||||
import type { ProfileDisplayData } from "@customer-portal/domain";
|
||||
import type { ProfileDisplayData } from "@customer-portal/domain/billing";
|
||||
|
||||
interface PersonalInfoCardProps {
|
||||
data: ProfileDisplayData;
|
||||
|
||||
@ -6,7 +6,7 @@ import {
|
||||
addressFormSchema,
|
||||
addressFormToRequest,
|
||||
type AddressFormData,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import { useZodForm } from "@customer-portal/validation";
|
||||
|
||||
export function useAddressEdit(initial: AddressFormData) {
|
||||
|
||||
@ -6,10 +6,10 @@ import { accountService } from "@/features/account/services/account.service";
|
||||
import { logger } from "@customer-portal/logging";
|
||||
|
||||
// Use centralized profile types
|
||||
import type { ProfileEditFormData } from "@customer-portal/domain";
|
||||
import type { ProfileEditFormData } from "@customer-portal/domain/billing";
|
||||
|
||||
// Address type moved to domain package
|
||||
import type { Address } from "@customer-portal/domain";
|
||||
import type { Address } from "@customer-portal/domain/billing";
|
||||
|
||||
export function useProfileData() {
|
||||
const { user } = useAuthStore();
|
||||
|
||||
@ -7,7 +7,7 @@ import {
|
||||
profileEditFormSchema,
|
||||
profileFormToRequest,
|
||||
type ProfileEditFormData,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import { useZodForm } from "@customer-portal/validation";
|
||||
|
||||
export function useProfileEdit(initial: ProfileEditFormData) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { apiClient, getDataOrThrow, getNullableData } from "@/lib/api";
|
||||
import type { Address, UserProfile } from "@customer-portal/domain";
|
||||
import type { Address, UserProfile } from "@customer-portal/domain/billing";
|
||||
|
||||
type ProfileUpdateInput = {
|
||||
firstName?: string;
|
||||
|
||||
@ -10,7 +10,7 @@ import Link from "next/link";
|
||||
import { Button, Input, ErrorMessage } from "@/components/atoms";
|
||||
import { FormField } from "@/components/molecules/FormField/FormField";
|
||||
import { useLogin } from "../../hooks/use-auth";
|
||||
import { loginFormSchema, loginFormToRequest } from "@customer-portal/domain";
|
||||
import { loginFormSchema, loginFormToRequest } from "@customer-portal/domain/billing";
|
||||
import { useZodForm } from "@customer-portal/validation";
|
||||
import { z } from "zod";
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ import {
|
||||
passwordResetFormSchema,
|
||||
type PasswordResetRequestFormData,
|
||||
type PasswordResetFormData,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import { z } from "zod";
|
||||
|
||||
interface PasswordResetFormProps {
|
||||
|
||||
@ -11,7 +11,7 @@ import { Button, Input, ErrorMessage } from "@/components/atoms";
|
||||
import { FormField } from "@/components/molecules/FormField/FormField";
|
||||
import { useWhmcsLink } from "../../hooks/use-auth";
|
||||
import { useZodForm } from "@customer-portal/validation";
|
||||
import { setPasswordFormSchema, type SetPasswordFormData } from "@customer-portal/domain";
|
||||
import { setPasswordFormSchema, type SetPasswordFormData } from "@customer-portal/domain/billing";
|
||||
import { z } from "zod";
|
||||
|
||||
interface SetPasswordFormProps {
|
||||
|
||||
@ -10,7 +10,7 @@ import {
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { StatusPill } from "@/components/atoms/status-pill";
|
||||
import type { StatusPillProps } from "@/components/atoms/status-pill";
|
||||
import type { InvoiceStatus } from "@customer-portal/domain";
|
||||
import type { InvoiceStatus } from "@customer-portal/domain/billing";
|
||||
|
||||
interface BillingStatusBadgeProps extends Omit<StatusPillProps, "variant" | "icon" | "label"> {
|
||||
status: string;
|
||||
|
||||
@ -10,8 +10,8 @@ import {
|
||||
ArrowRightIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { BillingStatusBadge } from "../BillingStatusBadge";
|
||||
import type { BillingSummaryData } from "@customer-portal/domain";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain";
|
||||
import type { BillingSummaryData } from "@customer-portal/domain/billing";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain/billing";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface BillingSummaryProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
|
||||
@ -8,8 +8,8 @@ import {
|
||||
ServerIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { format } from "date-fns";
|
||||
import type { Invoice } from "@customer-portal/domain";
|
||||
import { formatCurrency } from "@customer-portal/domain";
|
||||
import type { Invoice } from "@customer-portal/domain/billing";
|
||||
import { formatCurrency } from "@customer-portal/domain/billing";
|
||||
|
||||
const formatDate = (dateString?: string) => {
|
||||
if (!dateString || dateString === "0000-00-00" || dateString === "0000-00-00 00:00:00")
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
|
||||
import React from "react";
|
||||
import Link from "next/link";
|
||||
import { formatCurrency } from "@customer-portal/domain";
|
||||
import type { InvoiceItem } from "@customer-portal/domain";
|
||||
import { formatCurrency } from "@customer-portal/domain/billing";
|
||||
import type { InvoiceItem } from "@customer-portal/domain/billing";
|
||||
|
||||
interface InvoiceItemsProps {
|
||||
items?: InvoiceItem[];
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { useMemo } from "react";
|
||||
import { format, formatDistanceToNowStrict } from "date-fns";
|
||||
import { ArrowDownTrayIcon, ArrowTopRightOnSquareIcon } from "@heroicons/react/24/outline";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain";
|
||||
import type { Invoice } from "@customer-portal/domain";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain/billing";
|
||||
import type { Invoice } from "@customer-portal/domain/billing";
|
||||
import { Button } from "@/components/atoms/button";
|
||||
import { StatusPill } from "@/components/atoms/status-pill";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { formatCurrency } from "@customer-portal/domain";
|
||||
import { formatCurrency } from "@customer-portal/domain/billing";
|
||||
|
||||
interface InvoiceTotalsProps {
|
||||
subtotal: number;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
"use client";
|
||||
import { formatCurrency } from "@customer-portal/domain";
|
||||
import { formatCurrency } from "@customer-portal/domain/billing";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
export function InvoiceItemRow({
|
||||
|
||||
@ -9,7 +9,7 @@ import { PaginationBar } from "@/components/molecules/PaginationBar/PaginationBa
|
||||
import { InvoiceTable } from "@/features/billing/components/InvoiceTable/InvoiceTable";
|
||||
import { useInvoices } from "@/features/billing/hooks/useBilling";
|
||||
import { useSubscriptionInvoices } from "@/features/subscriptions/hooks/useSubscriptions";
|
||||
import type { Invoice } from "@customer-portal/domain";
|
||||
import type { Invoice } from "@customer-portal/domain/billing";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface InvoicesListProps {
|
||||
|
||||
@ -16,8 +16,8 @@ import { CheckCircleIcon as CheckCircleIconSolid } from "@heroicons/react/24/sol
|
||||
import { DataTable } from "@/components/molecules/DataTable/DataTable";
|
||||
import { Button } from "@/components/atoms/button";
|
||||
import { BillingStatusBadge } from "../BillingStatusBadge";
|
||||
import type { Invoice } from "@customer-portal/domain";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain";
|
||||
import type { Invoice } from "@customer-portal/domain/billing";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain/billing";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useCreateInvoiceSsoLink } from "@/features/billing/hooks/useBilling";
|
||||
import { openSsoLink } from "@/features/billing/utils/sso";
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { CreditCardIcon, BanknotesIcon, DevicePhoneMobileIcon, CheckCircleIcon } from "@heroicons/react/24/outline";
|
||||
import type { PaymentMethod } from "@customer-portal/domain";
|
||||
import type { PaymentMethod } from "@customer-portal/domain/billing";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
ArrowPathIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { Badge } from "@/components/atoms/badge";
|
||||
import type { PaymentMethod } from "@customer-portal/domain";
|
||||
import type { PaymentMethod } from "@customer-portal/domain/billing";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface PaymentMethodCardProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
|
||||
@ -16,12 +16,12 @@ import type {
|
||||
InvoiceList,
|
||||
InvoiceSsoLink,
|
||||
PaymentMethodList,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import {
|
||||
invoiceListSchema,
|
||||
invoiceSchema as sharedInvoiceSchema,
|
||||
} from "@customer-portal/domain/validation/shared/entities";
|
||||
import { INVOICE_STATUS } from "@customer-portal/domain";
|
||||
import { INVOICE_STATUS } from "@customer-portal/domain/billing";
|
||||
|
||||
const emptyInvoiceList: InvoiceList = {
|
||||
invoices: [],
|
||||
|
||||
@ -11,7 +11,7 @@ import { logger } from "@customer-portal/logging";
|
||||
import { apiClient, getDataOrThrow } from "@/lib/api";
|
||||
import { openSsoLink } from "@/features/billing/utils/sso";
|
||||
import { useInvoice, useCreateInvoiceSsoLink } from "@/features/billing/hooks";
|
||||
import type { InvoiceSsoLink } from "@customer-portal/domain";
|
||||
import type { InvoiceSsoLink } from "@customer-portal/domain/billing";
|
||||
import {
|
||||
InvoiceItems,
|
||||
InvoiceTotals,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { CheckCircleIcon } from "@heroicons/react/24/solid";
|
||||
import type { CatalogProductBase } from "@customer-portal/domain";
|
||||
import type { CatalogProductBase } from "@customer-portal/domain/billing";
|
||||
import { getMonthlyPrice, getOneTimePrice } from "../../utils/pricing";
|
||||
|
||||
interface AddonGroupProps {
|
||||
|
||||
@ -18,7 +18,7 @@ import {
|
||||
} from "@heroicons/react/24/outline";
|
||||
|
||||
// Use canonical Address type from domain
|
||||
import type { Address } from "@customer-portal/domain";
|
||||
import type { Address } from "@customer-portal/domain/billing";
|
||||
|
||||
interface BillingInfo {
|
||||
company: string | null;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
import { useEffect } from "react";
|
||||
import { MapPinIcon, ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||
import { useZodForm } from "@customer-portal/validation";
|
||||
import { addressFormSchema, type AddressFormData, type Address } from "@customer-portal/domain";
|
||||
import { addressFormSchema, type AddressFormData, type Address } from "@customer-portal/domain/billing";
|
||||
|
||||
export interface AddressFormProps {
|
||||
// Initial values
|
||||
|
||||
@ -12,7 +12,7 @@ import { Button } from "@/components/atoms/button";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
// Align with shared catalog contracts
|
||||
import type { CatalogProductBase } from "@customer-portal/domain";
|
||||
import type { CatalogProductBase } from "@customer-portal/domain/billing";
|
||||
|
||||
// Enhanced order item representation for UI summary
|
||||
export type OrderItem = CatalogProductBase & {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ArrowLeftIcon, ArrowRightIcon } from "@heroicons/react/24/outline";
|
||||
import type { CatalogProductBase } from "@customer-portal/domain";
|
||||
import type { CatalogProductBase } from "@customer-portal/domain/billing";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Button } from "@/components/atoms/button";
|
||||
import { getMonthlyPrice, getOneTimePrice } from "../../utils/pricing";
|
||||
|
||||
@ -5,7 +5,7 @@ import { Skeleton } from "@/components/atoms/loading-skeleton";
|
||||
import { Button } from "@/components/atoms/button";
|
||||
import { AlertBanner } from "@/components/molecules/AlertBanner/AlertBanner";
|
||||
import { CreditCardIcon, CheckCircleIcon } from "@heroicons/react/24/outline";
|
||||
import type { PaymentMethod } from "@customer-portal/domain";
|
||||
import type { PaymentMethod } from "@customer-portal/domain/billing";
|
||||
|
||||
export interface PaymentFormProps {
|
||||
existingMethods?: PaymentMethod[];
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import type { InternetInstallationCatalogItem } from "@customer-portal/domain";
|
||||
import type { InternetInstallationCatalogItem } from "@customer-portal/domain/billing";
|
||||
import { getDisplayPrice } from "../../utils/pricing";
|
||||
import {
|
||||
inferInstallationTypeFromSku,
|
||||
|
||||
@ -5,7 +5,7 @@ import type {
|
||||
InternetPlanCatalogItem,
|
||||
InternetInstallationCatalogItem,
|
||||
InternetAddonCatalogItem,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
|
||||
interface Props {
|
||||
plan: InternetPlanCatalogItem | null;
|
||||
|
||||
@ -6,7 +6,7 @@ import { CurrencyYenIcon, ArrowRightIcon } from "@heroicons/react/24/outline";
|
||||
import type {
|
||||
InternetPlanCatalogItem,
|
||||
InternetInstallationCatalogItem,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { getMonthlyPrice, getOneTimePrice } from "../../utils/pricing";
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import type {
|
||||
InternetPlanCatalogItem,
|
||||
InternetInstallationCatalogItem,
|
||||
InternetAddonCatalogItem,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import { ConfigureLoadingSkeleton } from "./components/ConfigureLoadingSkeleton";
|
||||
import { ServiceConfigurationStep } from "./steps/ServiceConfigurationStep";
|
||||
import { InstallationStep } from "./steps/InstallationStep";
|
||||
|
||||
@ -5,7 +5,7 @@ import type {
|
||||
InternetPlanCatalogItem,
|
||||
InternetInstallationCatalogItem,
|
||||
InternetAddonCatalogItem,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import type { AccessMode } from "../../../../hooks/useConfigureParams";
|
||||
import { getMonthlyPrice, getOneTimePrice } from "../../../../utils/pricing";
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import { Button } from "@/components/atoms/button";
|
||||
import { StepHeader } from "@/components/atoms";
|
||||
import { AddonGroup } from "@/features/catalog/components/base/AddonGroup";
|
||||
import { ArrowLeftIcon, ArrowRightIcon } from "@heroicons/react/24/outline";
|
||||
import type { InternetAddonCatalogItem } from "@customer-portal/domain";
|
||||
import type { InternetAddonCatalogItem } from "@customer-portal/domain/billing";
|
||||
|
||||
interface Props {
|
||||
addons: InternetAddonCatalogItem[];
|
||||
|
||||
@ -5,7 +5,7 @@ import { Button } from "@/components/atoms/button";
|
||||
import { StepHeader } from "@/components/atoms";
|
||||
import { InstallationOptions } from "../../InstallationOptions";
|
||||
import { ArrowLeftIcon, ArrowRightIcon } from "@heroicons/react/24/outline";
|
||||
import type { InternetInstallationCatalogItem } from "@customer-portal/domain";
|
||||
import type { InternetInstallationCatalogItem } from "@customer-portal/domain/billing";
|
||||
|
||||
interface Props {
|
||||
installations: InternetInstallationCatalogItem[];
|
||||
|
||||
@ -8,7 +8,7 @@ import type {
|
||||
InternetPlanCatalogItem,
|
||||
InternetInstallationCatalogItem,
|
||||
InternetAddonCatalogItem,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import type { AccessMode } from "../../../../hooks/useConfigureParams";
|
||||
import { getMonthlyPrice, getOneTimePrice } from "../../../../utils/pricing";
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import { Button } from "@/components/atoms/button";
|
||||
import { StepHeader } from "@/components/atoms";
|
||||
import { AlertBanner } from "@/components/molecules/AlertBanner/AlertBanner";
|
||||
import { ArrowRightIcon } from "@heroicons/react/24/outline";
|
||||
import type { InternetPlanCatalogItem } from "@customer-portal/domain";
|
||||
import type { InternetPlanCatalogItem } from "@customer-portal/domain/billing";
|
||||
import type { AccessMode } from "../../../../hooks/useConfigureParams";
|
||||
|
||||
interface Props {
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
import { DevicePhoneMobileIcon, UsersIcon, CurrencyYenIcon } from "@heroicons/react/24/outline";
|
||||
import { AnimatedCard } from "@/components/molecules/AnimatedCard/AnimatedCard";
|
||||
import { Button } from "@/components/atoms/button";
|
||||
import type { SimCatalogProduct } from "@customer-portal/domain";
|
||||
import type { SimCatalogProduct } from "@customer-portal/domain/billing";
|
||||
import { getMonthlyPrice } from "../../utils/pricing";
|
||||
|
||||
interface SimPlanCardProps {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
import React from "react";
|
||||
import { UsersIcon } from "@heroicons/react/24/outline";
|
||||
import type { SimCatalogProduct } from "@customer-portal/domain";
|
||||
import type { SimCatalogProduct } from "@customer-portal/domain/billing";
|
||||
import { SimPlanCard } from "./SimPlanCard";
|
||||
|
||||
interface SimPlanTypeSectionProps {
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
import { AnimatedCard } from "@/components/molecules";
|
||||
import { Button } from "@/components/atoms/button";
|
||||
import { CurrencyYenIcon } from "@heroicons/react/24/outline";
|
||||
import type { VpnCatalogProduct } from "@customer-portal/domain";
|
||||
import type { VpnCatalogProduct } from "@customer-portal/domain/billing";
|
||||
|
||||
interface VpnPlanCardProps {
|
||||
plan: VpnCatalogProduct;
|
||||
|
||||
@ -7,7 +7,7 @@ import type {
|
||||
InternetPlanCatalogItem,
|
||||
InternetInstallationCatalogItem,
|
||||
InternetAddonCatalogItem,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import { inferInstallationTypeFromSku } from "../utils/inferInstallationType";
|
||||
import { getMonthlyPrice, getOneTimePrice } from "../utils/pricing";
|
||||
|
||||
|
||||
@ -11,8 +11,8 @@ import {
|
||||
type SimType,
|
||||
type ActivationType,
|
||||
type MnpData,
|
||||
} from "@customer-portal/domain";
|
||||
import type { SimCatalogProduct, SimActivationFeeCatalogItem } from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import type { SimCatalogProduct, SimActivationFeeCatalogItem } from "@customer-portal/domain/billing";
|
||||
|
||||
export type UseSimConfigureResult = {
|
||||
// data
|
||||
|
||||
@ -12,7 +12,7 @@ export * from "./hooks";
|
||||
// Services
|
||||
export * from "./services";
|
||||
|
||||
// Import domain types directly: import type { Address } from "@customer-portal/domain";
|
||||
// Import domain types directly: import type { Address } from "@customer-portal/domain/billing";
|
||||
|
||||
// Utilities
|
||||
export * from "./utils";
|
||||
|
||||
@ -6,7 +6,7 @@ import type {
|
||||
SimCatalogProduct,
|
||||
SimActivationFeeCatalogItem,
|
||||
VpnCatalogProduct,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
|
||||
const emptyInternetPlans: InternetPlanCatalogItem[] = [];
|
||||
const emptyInternetAddons: InternetAddonCatalogItem[] = [];
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* Helper functions for catalog operations
|
||||
*/
|
||||
|
||||
import { formatCurrency } from "@customer-portal/domain";
|
||||
import { formatCurrency } from "@customer-portal/domain/billing";
|
||||
import type {
|
||||
CatalogFilter,
|
||||
InternetPlanCatalogItem,
|
||||
@ -11,7 +11,7 @@ import type {
|
||||
InternetInstallationCatalogItem,
|
||||
SimCatalogProduct,
|
||||
VpnCatalogProduct,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
|
||||
type CatalogProduct =
|
||||
| InternetPlanCatalogItem
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { CatalogProductBase } from "@customer-portal/domain";
|
||||
import type { CatalogProductBase } from "@customer-portal/domain/billing";
|
||||
|
||||
export function getMonthlyPrice(product?: CatalogProductBase | null): number {
|
||||
if (!product) return 0;
|
||||
|
||||
@ -17,7 +17,7 @@ import type {
|
||||
InternetPlanCatalogItem,
|
||||
InternetInstallationCatalogItem,
|
||||
InternetAddonCatalogItem,
|
||||
} from "@customer-portal/domain";
|
||||
} from "@customer-portal/domain/billing";
|
||||
import { getMonthlyPrice } from "../utils/pricing";
|
||||
import { LoadingCard, Skeleton, LoadingTable } from "@/components/atoms/loading-skeleton";
|
||||
import { AnimatedCard } from "@/components/molecules";
|
||||
|
||||
@ -15,7 +15,7 @@ import { LoadingCard, Skeleton } from "@/components/atoms/loading-skeleton";
|
||||
import { Button } from "@/components/atoms/button";
|
||||
import { AlertBanner } from "@/components/molecules/AlertBanner/AlertBanner";
|
||||
import { useSimCatalog } from "@/features/catalog/hooks";
|
||||
import type { SimCatalogProduct } from "@customer-portal/domain";
|
||||
import type { SimCatalogProduct } from "@customer-portal/domain/billing";
|
||||
import { SimPlanTypeSection } from "@/features/catalog/components/sim/SimPlanTypeSection";
|
||||
|
||||
interface PlansByType {
|
||||
|
||||
@ -7,13 +7,13 @@ import { ordersService } from "@/features/orders/services/orders.service";
|
||||
import { usePaymentMethods } from "@/features/billing/hooks/useBilling";
|
||||
import { usePaymentRefresh } from "@/features/billing/hooks/usePaymentRefresh";
|
||||
import { getMonthlyPrice, getOneTimePrice } from "@/features/catalog/utils/pricing";
|
||||
import type { CatalogProductBase } from "@customer-portal/domain";
|
||||
import { createLoadingState, createSuccessState, createErrorState } from "@customer-portal/domain";
|
||||
import type { AsyncState } from "@customer-portal/domain";
|
||||
import type { CatalogProductBase } from "@customer-portal/domain/billing";
|
||||
import { createLoadingState, createSuccessState, createErrorState } from "@customer-portal/domain/billing";
|
||||
import type { AsyncState } from "@customer-portal/domain/billing";
|
||||
import { useActiveSubscriptions } from "@/features/subscriptions/hooks/useSubscriptions";
|
||||
|
||||
// Use domain Address type
|
||||
import type { Address } from "@customer-portal/domain";
|
||||
import type { Address } from "@customer-portal/domain/billing";
|
||||
|
||||
type CheckoutItemType = "plan" | "installation" | "addon" | "activation" | "vpn";
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ import { PageAsync } from "@/components/molecules/AsyncBlock/AsyncBlock";
|
||||
import { InlineToast } from "@/components/atoms/inline-toast";
|
||||
import { StatusPill } from "@/components/atoms/status-pill";
|
||||
import { AddressConfirmation } from "@/features/catalog/components/base/AddressConfirmation";
|
||||
import { isLoading, isError, isSuccess } from "@customer-portal/domain";
|
||||
import { isLoading, isError, isSuccess } from "@customer-portal/domain/billing";
|
||||
import {
|
||||
ExclamationTriangleIcon,
|
||||
ShieldCheckIcon,
|
||||
|
||||
@ -10,8 +10,8 @@ import {
|
||||
getActivityNavigationPath,
|
||||
isActivityClickable,
|
||||
} from "../utils/dashboard.utils";
|
||||
import type { Activity } from "@customer-portal/domain";
|
||||
import type { ActivityFilter } from "@customer-portal/domain";
|
||||
import type { Activity } from "@customer-portal/domain/billing";
|
||||
import type { ActivityFilter } from "@customer-portal/domain/billing";
|
||||
|
||||
export interface ActivityFeedProps {
|
||||
activities: Activity[];
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
import Link from "next/link";
|
||||
import { CalendarDaysIcon, ChevronRightIcon } from "@heroicons/react/24/outline";
|
||||
import { format, formatDistanceToNow } from "date-fns";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain/billing";
|
||||
|
||||
interface UpcomingPaymentBannerProps {
|
||||
invoice: { id: number; amount: number; currency?: string; dueDate: string };
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useAuthSession } from "@/features/auth/services/auth.store";
|
||||
import { apiClient, queryKeys, getDataOrThrow } from "@/lib/api";
|
||||
import type { DashboardSummary, DashboardError } from "@customer-portal/domain";
|
||||
import type { DashboardSummary, DashboardError } from "@customer-portal/domain/billing";
|
||||
|
||||
class DashboardDataError extends Error {
|
||||
constructor(
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
* Helper functions for dashboard data processing and formatting
|
||||
*/
|
||||
|
||||
import type { Activity } from "@customer-portal/domain";
|
||||
import type { ActivityFilter, ActivityFilterConfig } from "@customer-portal/domain";
|
||||
import type { Activity } from "@customer-portal/domain/billing";
|
||||
import type { ActivityFilter, ActivityFilterConfig } from "@customer-portal/domain/billing";
|
||||
|
||||
/**
|
||||
* Activity filter configurations
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import type { Activity, DashboardSummary } from "@customer-portal/domain";
|
||||
import type { Activity, DashboardSummary } from "@customer-portal/domain/billing";
|
||||
import {
|
||||
ServerIcon,
|
||||
ChatBubbleLeftRightIcon,
|
||||
@ -25,7 +25,7 @@ import { useDashboardSummary } from "@/features/dashboard/hooks";
|
||||
import { StatCard, QuickAction, DashboardActivityItem } from "@/features/dashboard/components";
|
||||
import { LoadingStats, LoadingTable } from "@/components/atoms";
|
||||
import { ErrorState } from "@/components/atoms/error-state";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain/billing";
|
||||
import { log } from "@customer-portal/logging";
|
||||
import { useCreateInvoiceSsoLink } from "@/features/billing/hooks/useBilling";
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { apiClient } from "@/lib/api";
|
||||
import type { CreateOrderRequest } from "@customer-portal/domain";
|
||||
import type { CreateOrderRequest } from "@customer-portal/domain/billing";
|
||||
|
||||
async function createOrder<T = { sfOrderId: string }>(payload: CreateOrderRequest): Promise<T> {
|
||||
const response = await apiClient.POST("/api/orders", { body: payload });
|
||||
|
||||
@ -11,7 +11,7 @@ import {
|
||||
ExclamationTriangleIcon,
|
||||
XCircleIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import type { SimDetails } from "@customer-portal/contracts/sim";
|
||||
import type { SimDetails } from "@customer-portal/domain/sim";
|
||||
|
||||
interface SimDetailsCardProps {
|
||||
simDetails: SimDetails;
|
||||
|
||||
@ -15,8 +15,8 @@ import {
|
||||
import { StatusPill } from "@/components/atoms/status-pill";
|
||||
import { Button } from "@/components/atoms/button";
|
||||
import { SubCard } from "@/components/molecules/SubCard/SubCard";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain";
|
||||
import type { Subscription } from "@customer-portal/domain";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain/billing";
|
||||
import type { Subscription } from "@customer-portal/domain/billing";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface SubscriptionCardProps {
|
||||
|
||||
@ -15,8 +15,8 @@ import {
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { StatusPill } from "@/components/atoms/status-pill";
|
||||
import { SubCard } from "@/components/molecules/SubCard/SubCard";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain";
|
||||
import type { Subscription } from "@customer-portal/domain";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain/billing";
|
||||
import type { Subscription } from "@customer-portal/domain/billing";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface SubscriptionDetailsProps {
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { apiClient, queryKeys, getDataOrDefault, getDataOrThrow, getNullableData } from "@/lib/api";
|
||||
import { useAuthSession } from "@/features/auth/services";
|
||||
import type { InvoiceList, Subscription, SubscriptionList } from "@customer-portal/domain";
|
||||
import type { InvoiceList, Subscription, SubscriptionList } from "@customer-portal/domain/billing";
|
||||
|
||||
interface UseSubscriptionsOptions {
|
||||
status?: string;
|
||||
|
||||
@ -20,7 +20,7 @@ import {
|
||||
import { format } from "date-fns";
|
||||
import { useSubscription } from "@/features/subscriptions/hooks";
|
||||
import { InvoicesList } from "@/features/billing/components/InvoiceList/InvoiceList";
|
||||
import { formatCurrency as sharedFormatCurrency, getCurrencyLocale } from "@customer-portal/domain";
|
||||
import { formatCurrency as sharedFormatCurrency, getCurrencyLocale } from "@customer-portal/domain/billing";
|
||||
import { SimManagementSection } from "@/features/sim-management";
|
||||
|
||||
export function SubscriptionDetailContainer() {
|
||||
|
||||
@ -23,8 +23,8 @@ import {
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { format } from "date-fns";
|
||||
import { useSubscriptions, useSubscriptionStats } from "@/features/subscriptions/hooks";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain";
|
||||
import type { Subscription } from "@customer-portal/domain";
|
||||
import { formatCurrency, getCurrencyLocale } from "@customer-portal/domain/billing";
|
||||
import type { Subscription } from "@customer-portal/domain/billing";
|
||||
|
||||
export function SubscriptionsListContainer() {
|
||||
const router = useRouter();
|
||||
|
||||
@ -91,12 +91,4 @@ export const authResponseSchema = z.object({
|
||||
tokens: authTokensSchema,
|
||||
});
|
||||
|
||||
export const validateSignupRequestSchema = signupRequestSchema.pick({ sfNumber: true });
|
||||
export const accountStatusRequestSchema = z.object({ email: emailSchema });
|
||||
export const ssoLinkRequestSchema = z.object({ destination: z.string().optional() });
|
||||
export const checkPasswordNeededRequestSchema = z.object({ email: emailSchema });
|
||||
export const refreshTokenRequestSchema = z.object({
|
||||
refreshToken: z.string().min(1, "Refresh token is required").optional(),
|
||||
deviceId: z.string().optional(),
|
||||
});
|
||||
|
||||
|
||||
@ -39,6 +39,14 @@ export type CancelPlanRequest = Requests.FreebitCancelPlanRequest;
|
||||
export type CancelPlanApiRequest = Requests.FreebitCancelPlanApiRequest;
|
||||
export type CancelAccountRequest = Requests.FreebitCancelAccountRequest;
|
||||
export type AuthRequest = Requests.FreebitAuthRequest;
|
||||
export type TopUpResponse = ReturnType<typeof Mapper.transformFreebitTopUpResponse>;
|
||||
export type AddSpecResponse = ReturnType<typeof Mapper.transformFreebitAddSpecResponse>;
|
||||
export type PlanChangeResponse = ReturnType<typeof Mapper.transformFreebitPlanChangeResponse>;
|
||||
export type CancelPlanResponse = ReturnType<typeof Mapper.transformFreebitCancelPlanResponse>;
|
||||
export type CancelAccountResponse = ReturnType<typeof Mapper.transformFreebitCancelAccountResponse>;
|
||||
export type EsimReissueResponse = ReturnType<typeof Mapper.transformFreebitEsimReissueResponse>;
|
||||
export type EsimAddAccountResponse = ReturnType<typeof Mapper.transformFreebitEsimAddAccountResponse>;
|
||||
export type EsimActivationResponse = ReturnType<typeof Mapper.transformFreebitEsimActivationResponse>;
|
||||
|
||||
export * from "./mapper";
|
||||
export * from "./raw.types";
|
||||
|
||||
@ -125,16 +125,12 @@ export function transformFreebitTrafficInfo(raw: unknown): SimUsage {
|
||||
|
||||
const simUsage: SimUsage = {
|
||||
account: asString(response.account),
|
||||
todayUsageMb: asNumber(response.todayData) / 1024,
|
||||
todayUsageKb: asNumber(response.todayData),
|
||||
monthlyUsageMb: response.thisMonthData ? asNumber(response.thisMonthData) / 1024 : undefined,
|
||||
monthlyUsageKb: response.thisMonthData ? asNumber(response.thisMonthData) : undefined,
|
||||
recentDaysUsage: (response.daily || []).map(day => ({
|
||||
date: day.usageDate || "",
|
||||
usageKb: asNumber(day.trafficKb),
|
||||
usageMb: asNumber(day.trafficKb) / 1024,
|
||||
})),
|
||||
isBlacklisted: parseBooleanFlag(response.blacklistFlg),
|
||||
todayUsageMb: response.traffic?.today ? asNumber(response.traffic.today) / 1024 : 0,
|
||||
todayUsageKb: response.traffic?.today ? asNumber(response.traffic.today) : 0,
|
||||
monthlyUsageMb: undefined,
|
||||
monthlyUsageKb: undefined,
|
||||
recentDaysUsage: [],
|
||||
isBlacklisted: parseBooleanFlag(response.traffic?.blackList),
|
||||
lastUpdated: new Date().toISOString(),
|
||||
};
|
||||
|
||||
@ -146,9 +142,9 @@ export function transformFreebitQuotaHistory(raw: unknown): SimTopUpHistory {
|
||||
|
||||
const history: SimTopUpHistory = {
|
||||
account: asString(response.account),
|
||||
totalAdditions: asNumber(response.totalAddQuotaKb),
|
||||
additionCount: asNumber(response.addQuotaCount),
|
||||
history: (response.details || []).map(detail => ({
|
||||
totalAdditions: asNumber(response.total),
|
||||
additionCount: asNumber(response.count),
|
||||
history: (response.quotaHistory || []).map(detail => ({
|
||||
quotaKb: asNumber(detail.addQuotaKb),
|
||||
quotaMb: asNumber(detail.addQuotaKb) / 1024,
|
||||
addedDate: detail.addDate || "",
|
||||
@ -168,27 +164,46 @@ export function transformFreebitTopUpResponse(raw: unknown) {
|
||||
return freebitTopUpRawSchema.parse(raw);
|
||||
}
|
||||
|
||||
export type FreebitTopUpResponse = ReturnType<typeof transformFreebitTopUpResponse>;
|
||||
|
||||
export function transformFreebitAddSpecResponse(raw: unknown) {
|
||||
return freebitAddSpecRawSchema.parse(raw);
|
||||
}
|
||||
|
||||
export type FreebitAddSpecResponse = ReturnType<typeof transformFreebitAddSpecResponse>;
|
||||
|
||||
export function transformFreebitPlanChangeResponse(raw: unknown) {
|
||||
return freebitPlanChangeRawSchema.parse(raw);
|
||||
}
|
||||
|
||||
export type FreebitPlanChangeResponse = ReturnType<typeof transformFreebitPlanChangeResponse>;
|
||||
|
||||
export function transformFreebitCancelPlanResponse(raw: unknown) {
|
||||
return freebitCancelPlanRawSchema.parse(raw);
|
||||
}
|
||||
|
||||
export type FreebitCancelPlanResponse = ReturnType<typeof transformFreebitCancelPlanResponse>;
|
||||
|
||||
export function transformFreebitCancelAccountResponse(raw: unknown) {
|
||||
return freebitCancelAccountRawSchema.parse(raw);
|
||||
}
|
||||
|
||||
export type FreebitCancelAccountResponse = ReturnType<typeof transformFreebitCancelAccountResponse>;
|
||||
|
||||
export function transformFreebitEsimReissueResponse(raw: unknown) {
|
||||
return freebitEsimReissueRawSchema.parse(raw);
|
||||
}
|
||||
|
||||
export type FreebitEsimReissueResponse = ReturnType<typeof transformFreebitEsimReissueResponse>;
|
||||
|
||||
export function transformFreebitEsimAddAccountResponse(raw: unknown) {
|
||||
return freebitEsimAddAccountRawSchema.parse(raw);
|
||||
}
|
||||
|
||||
export type FreebitEsimAddAccountResponse = ReturnType<typeof transformFreebitEsimAddAccountResponse>;
|
||||
|
||||
export function transformFreebitEsimActivationResponse(raw: unknown) {
|
||||
return freebitEsimAddAccountRawSchema.parse(raw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -145,11 +145,16 @@ export type FreebitTrafficInfoRaw = z.infer<typeof freebitTrafficInfoRawSchema>;
|
||||
// Freebit Quota History Response
|
||||
export const freebitQuotaHistoryRawSchema = z.object({
|
||||
resultCode: z.string().optional(),
|
||||
resultMessage: z.string().optional(),
|
||||
status: z
|
||||
.object({
|
||||
message: z.string().optional(),
|
||||
statusCode: z.union([z.string(), z.number()]).optional(),
|
||||
})
|
||||
.optional(),
|
||||
account: z.union([z.string(), z.number()]).optional(),
|
||||
totalAddQuotaKb: z.union([z.string(), z.number()]).optional(),
|
||||
addQuotaCount: z.union([z.string(), z.number()]).optional(),
|
||||
details: z.array(
|
||||
total: z.union([z.string(), z.number()]).optional(),
|
||||
count: z.union([z.string(), z.number()]).optional(),
|
||||
quotaHistory: z.array(
|
||||
z.object({
|
||||
addQuotaKb: z.union([z.string(), z.number()]).optional(),
|
||||
addDate: z.string().optional(),
|
||||
|
||||
@ -90,6 +90,37 @@ export const freebitCancelPlanApiRequestSchema = z.object({
|
||||
runTime: z.string().optional(),
|
||||
});
|
||||
|
||||
export const freebitQuotaHistoryRequestSchema = z.object({
|
||||
account: z.string().min(1, "Account is required"),
|
||||
fromDate: z.string().regex(/^\d{8}$/, "From date must be in YYYYMMDD format"),
|
||||
toDate: z.string().regex(/^\d{8}$/, "To date must be in YYYYMMDD format"),
|
||||
});
|
||||
|
||||
export const freebitQuotaHistoryResponseSchema = z.object({
|
||||
resultCode: z.string(),
|
||||
status: z
|
||||
.object({
|
||||
message: z.string(),
|
||||
statusCode: z.union([z.string(), z.number()]),
|
||||
})
|
||||
.optional(),
|
||||
total: z.union([z.string(), z.number()]),
|
||||
count: z.union([z.string(), z.number()]),
|
||||
quotaHistory: z.array(
|
||||
z.object({
|
||||
addQuotaKb: z.union([z.string(), z.number()]),
|
||||
addDate: z.string(),
|
||||
expireDate: z.string(),
|
||||
campaignCode: z.string().optional(),
|
||||
})
|
||||
),
|
||||
});
|
||||
|
||||
export const freebitEsimMnpSchema = z.object({
|
||||
reserveNumber: z.string().min(1, "Reserve number is required"),
|
||||
reserveExpireDate: z.string().regex(/^\d{8}$/, "Reserve expire date must be in YYYYMMDD format"),
|
||||
});
|
||||
|
||||
export const freebitEsimReissueRequestSchema = z.object({
|
||||
account: z.string().min(1, "Account is required"),
|
||||
newEid: z.string().min(1, "New EID is required"),
|
||||
@ -98,9 +129,21 @@ export const freebitEsimReissueRequestSchema = z.object({
|
||||
oldProductNumber: z.string().optional(),
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
export const freebitEsimAddAccountRequestSchema = z.object({
|
||||
authKey: z.string().min(1).optional(),
|
||||
aladinOperated: z.enum(["10", "20"]).default("10"),
|
||||
account: z.string().min(1, "Account is required"),
|
||||
eid: z.string().min(1, "EID is required"),
|
||||
addKind: z.enum(["N", "R"]).default("N"),
|
||||
shipDate: z.string().regex(/^\d{8}$/, "Ship date must be in YYYYMMDD format").optional(),
|
||||
planCode: z.string().optional(),
|
||||
contractLine: z.enum(["4G", "5G"]).optional(),
|
||||
mnp: freebitEsimMnpSchema.optional(),
|
||||
});
|
||||
|
||||
// =========================================================================
|
||||
// SIM Features
|
||||
// ============================================================================
|
||||
// =========================================================================
|
||||
|
||||
export const freebitSimFeaturesRequestSchema = z.object({
|
||||
account: z.string().min(1, "Account is required"),
|
||||
@ -115,14 +158,9 @@ export const freebitGlobalIpRequestSchema = z.object({
|
||||
assign: z.boolean(), // true to assign, false to remove
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// =========================================================================
|
||||
// eSIM Activation
|
||||
// ============================================================================
|
||||
|
||||
export const freebitEsimMnpSchema = z.object({
|
||||
reserveNumber: z.string().min(1, "Reserve number is required"),
|
||||
reserveExpireDate: z.string().regex(/^\d{8}$/, "Reserve expire date must be in YYYYMMDD format"),
|
||||
});
|
||||
// =========================================================================
|
||||
|
||||
export const freebitAuthRequestSchema = z.object({
|
||||
oemId: z.string().min(1),
|
||||
|
||||
116
packages/domain/src/common.d.ts
vendored
116
packages/domain/src/common.d.ts
vendored
@ -1,116 +0,0 @@
|
||||
export type UserId = string & {
|
||||
readonly __brand: "UserId";
|
||||
};
|
||||
export type OrderId = string & {
|
||||
readonly __brand: "OrderId";
|
||||
};
|
||||
export type InvoiceId = string & {
|
||||
readonly __brand: "InvoiceId";
|
||||
};
|
||||
export type SubscriptionId = string & {
|
||||
readonly __brand: "SubscriptionId";
|
||||
};
|
||||
export type PaymentId = string & {
|
||||
readonly __brand: "PaymentId";
|
||||
};
|
||||
export type CaseId = string & {
|
||||
readonly __brand: "CaseId";
|
||||
};
|
||||
export type SessionId = string & {
|
||||
readonly __brand: "SessionId";
|
||||
};
|
||||
export type WhmcsClientId = number & {
|
||||
readonly __brand: "WhmcsClientId";
|
||||
};
|
||||
export type WhmcsInvoiceId = number & {
|
||||
readonly __brand: "WhmcsInvoiceId";
|
||||
};
|
||||
export type WhmcsProductId = number & {
|
||||
readonly __brand: "WhmcsProductId";
|
||||
};
|
||||
export type SalesforceContactId = string & {
|
||||
readonly __brand: "SalesforceContactId";
|
||||
};
|
||||
export type SalesforceAccountId = string & {
|
||||
readonly __brand: "SalesforceAccountId";
|
||||
};
|
||||
export type SalesforceCaseId = string & {
|
||||
readonly __brand: "SalesforceCaseId";
|
||||
};
|
||||
export declare const createUserId: (id: string) => UserId;
|
||||
export declare const createOrderId: (id: string) => OrderId;
|
||||
export declare const createInvoiceId: (id: string) => InvoiceId;
|
||||
export declare const createSubscriptionId: (id: string) => SubscriptionId;
|
||||
export declare const createPaymentId: (id: string) => PaymentId;
|
||||
export declare const createCaseId: (id: string) => CaseId;
|
||||
export declare const createSessionId: (id: string) => SessionId;
|
||||
export declare const createWhmcsClientId: (id: number) => WhmcsClientId;
|
||||
export declare const createWhmcsInvoiceId: (id: number) => WhmcsInvoiceId;
|
||||
export declare const createWhmcsProductId: (id: number) => WhmcsProductId;
|
||||
export declare const createSalesforceContactId: (id: string) => SalesforceContactId;
|
||||
export declare const createSalesforceAccountId: (id: string) => SalesforceAccountId;
|
||||
export declare const createSalesforceCaseId: (id: string) => SalesforceCaseId;
|
||||
export declare const isUserId: (id: string) => id is UserId;
|
||||
export declare const isOrderId: (id: string) => id is OrderId;
|
||||
export declare const isInvoiceId: (id: string) => id is InvoiceId;
|
||||
export declare const isWhmcsClientId: (id: number) => id is WhmcsClientId;
|
||||
export type IsoDateTimeString = string;
|
||||
export interface BaseEntity {
|
||||
id: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
export interface WhmcsEntity {
|
||||
id: number;
|
||||
}
|
||||
export interface SalesforceEntity {
|
||||
id: string;
|
||||
createdDate: string;
|
||||
lastModifiedDate: string;
|
||||
}
|
||||
export interface Paginated<T> {
|
||||
items: T[];
|
||||
nextCursor: string | null;
|
||||
totalCount?: number;
|
||||
}
|
||||
export interface IdempotencyKey {
|
||||
key: string;
|
||||
userId: string;
|
||||
createdAt: string;
|
||||
}
|
||||
export interface UserMapping {
|
||||
userId: string;
|
||||
whmcsClientId: number;
|
||||
sfContactId?: string;
|
||||
sfAccountId?: string;
|
||||
createdAt?: Date;
|
||||
updatedAt?: Date;
|
||||
}
|
||||
export interface UserIdMapping extends UserMapping {
|
||||
createdAt?: Date;
|
||||
updatedAt?: Date;
|
||||
}
|
||||
export interface CreateMappingRequest {
|
||||
userId: string;
|
||||
whmcsClientId: number;
|
||||
sfAccountId?: string;
|
||||
}
|
||||
export interface UpdateMappingRequest {
|
||||
whmcsClientId?: number;
|
||||
sfAccountId?: string;
|
||||
}
|
||||
export interface MappingStats {
|
||||
totalMappings: number;
|
||||
whmcsMappings: number;
|
||||
salesforceMappings: number;
|
||||
completeMappings: number;
|
||||
orphanedMappings: number;
|
||||
}
|
||||
export interface Address {
|
||||
street: string | null;
|
||||
streetLine2: string | null;
|
||||
city: string | null;
|
||||
state: string | null;
|
||||
postalCode: string | null;
|
||||
country: string | null;
|
||||
}
|
||||
@ -1,38 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isWhmcsClientId = exports.isInvoiceId = exports.isOrderId = exports.isUserId = exports.createSalesforceCaseId = exports.createSalesforceAccountId = exports.createSalesforceContactId = exports.createWhmcsProductId = exports.createWhmcsInvoiceId = exports.createWhmcsClientId = exports.createSessionId = exports.createCaseId = exports.createPaymentId = exports.createSubscriptionId = exports.createInvoiceId = exports.createOrderId = exports.createUserId = void 0;
|
||||
const createUserId = (id) => id;
|
||||
exports.createUserId = createUserId;
|
||||
const createOrderId = (id) => id;
|
||||
exports.createOrderId = createOrderId;
|
||||
const createInvoiceId = (id) => id;
|
||||
exports.createInvoiceId = createInvoiceId;
|
||||
const createSubscriptionId = (id) => id;
|
||||
exports.createSubscriptionId = createSubscriptionId;
|
||||
const createPaymentId = (id) => id;
|
||||
exports.createPaymentId = createPaymentId;
|
||||
const createCaseId = (id) => id;
|
||||
exports.createCaseId = createCaseId;
|
||||
const createSessionId = (id) => id;
|
||||
exports.createSessionId = createSessionId;
|
||||
const createWhmcsClientId = (id) => id;
|
||||
exports.createWhmcsClientId = createWhmcsClientId;
|
||||
const createWhmcsInvoiceId = (id) => id;
|
||||
exports.createWhmcsInvoiceId = createWhmcsInvoiceId;
|
||||
const createWhmcsProductId = (id) => id;
|
||||
exports.createWhmcsProductId = createWhmcsProductId;
|
||||
const createSalesforceContactId = (id) => id;
|
||||
exports.createSalesforceContactId = createSalesforceContactId;
|
||||
const createSalesforceAccountId = (id) => id;
|
||||
exports.createSalesforceAccountId = createSalesforceAccountId;
|
||||
const createSalesforceCaseId = (id) => id;
|
||||
exports.createSalesforceCaseId = createSalesforceCaseId;
|
||||
const isUserId = (id) => typeof id === "string";
|
||||
exports.isUserId = isUserId;
|
||||
const isOrderId = (id) => typeof id === "string";
|
||||
exports.isOrderId = isOrderId;
|
||||
const isInvoiceId = (id) => typeof id === "string";
|
||||
exports.isInvoiceId = isInvoiceId;
|
||||
const isWhmcsClientId = (id) => typeof id === "number";
|
||||
exports.isWhmcsClientId = isWhmcsClientId;
|
||||
//# sourceMappingURL=common.js.map
|
||||
@ -1 +0,0 @@
|
||||
{"version":3,"file":"common.js","sourceRoot":"","sources":["common.ts"],"names":[],"mappings":";;;AA0BO,MAAM,YAAY,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,EAAY,CAAC;AAApD,QAAA,YAAY,gBAAwC;AAC1D,MAAM,aAAa,GAAG,CAAC,EAAU,EAAW,EAAE,CAAC,EAAa,CAAC;AAAvD,QAAA,aAAa,iBAA0C;AAC7D,MAAM,eAAe,GAAG,CAAC,EAAU,EAAa,EAAE,CAAC,EAAe,CAAC;AAA7D,QAAA,eAAe,mBAA8C;AACnE,MAAM,oBAAoB,GAAG,CAAC,EAAU,EAAkB,EAAE,CAAC,EAAoB,CAAC;AAA5E,QAAA,oBAAoB,wBAAwD;AAClF,MAAM,eAAe,GAAG,CAAC,EAAU,EAAa,EAAE,CAAC,EAAe,CAAC;AAA7D,QAAA,eAAe,mBAA8C;AACnE,MAAM,YAAY,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,EAAY,CAAC;AAApD,QAAA,YAAY,gBAAwC;AAC1D,MAAM,eAAe,GAAG,CAAC,EAAU,EAAa,EAAE,CAAC,EAAe,CAAC;AAA7D,QAAA,eAAe,mBAA8C;AAEnE,MAAM,mBAAmB,GAAG,CAAC,EAAU,EAAiB,EAAE,CAAC,EAAmB,CAAC;AAAzE,QAAA,mBAAmB,uBAAsD;AAC/E,MAAM,oBAAoB,GAAG,CAAC,EAAU,EAAkB,EAAE,CAAC,EAAoB,CAAC;AAA5E,QAAA,oBAAoB,wBAAwD;AAClF,MAAM,oBAAoB,GAAG,CAAC,EAAU,EAAkB,EAAE,CAAC,EAAoB,CAAC;AAA5E,QAAA,oBAAoB,wBAAwD;AAElF,MAAM,yBAAyB,GAAG,CAAC,EAAU,EAAuB,EAAE,CAC3E,EAAyB,CAAC;AADf,QAAA,yBAAyB,6BACV;AACrB,MAAM,yBAAyB,GAAG,CAAC,EAAU,EAAuB,EAAE,CAC3E,EAAyB,CAAC;AADf,QAAA,yBAAyB,6BACV;AACrB,MAAM,sBAAsB,GAAG,CAAC,EAAU,EAAoB,EAAE,CAAC,EAAsB,CAAC;AAAlF,QAAA,sBAAsB,0BAA4D;AAGxF,MAAM,QAAQ,GAAG,CAAC,EAAU,EAAgB,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC;AAAhE,QAAA,QAAQ,YAAwD;AACtE,MAAM,SAAS,GAAG,CAAC,EAAU,EAAiB,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC;AAAlE,QAAA,SAAS,aAAyD;AACxE,MAAM,WAAW,GAAG,CAAC,EAAU,EAAmB,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC;AAAtE,QAAA,WAAW,eAA2D;AAC5E,MAAM,eAAe,GAAG,CAAC,EAAU,EAAuB,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC;AAA9E,QAAA,eAAe,mBAA+D"}
|
||||
@ -1,135 +0,0 @@
|
||||
// Common types used across the application
|
||||
|
||||
// =====================================================
|
||||
// BRANDED TYPES FOR TYPE SAFETY
|
||||
// =====================================================
|
||||
|
||||
// Branded types for critical identifiers
|
||||
export type UserId = string & { readonly __brand: "UserId" };
|
||||
export type OrderId = string & { readonly __brand: "OrderId" };
|
||||
export type InvoiceId = string & { readonly __brand: "InvoiceId" };
|
||||
export type SubscriptionId = string & { readonly __brand: "SubscriptionId" };
|
||||
export type PaymentId = string & { readonly __brand: "PaymentId" };
|
||||
export type CaseId = string & { readonly __brand: "CaseId" };
|
||||
export type SessionId = string & { readonly __brand: "SessionId" };
|
||||
|
||||
// WHMCS-specific branded types
|
||||
export type WhmcsClientId = number & { readonly __brand: "WhmcsClientId" };
|
||||
export type WhmcsInvoiceId = number & { readonly __brand: "WhmcsInvoiceId" };
|
||||
export type WhmcsProductId = number & { readonly __brand: "WhmcsProductId" };
|
||||
|
||||
// Salesforce-specific branded types
|
||||
export type SalesforceContactId = string & { readonly __brand: "SalesforceContactId" };
|
||||
export type SalesforceAccountId = string & { readonly __brand: "SalesforceAccountId" };
|
||||
export type SalesforceCaseId = string & { readonly __brand: "SalesforceCaseId" };
|
||||
|
||||
// Helper functions for creating branded types
|
||||
export const createUserId = (id: string): UserId => id as UserId;
|
||||
export const createOrderId = (id: string): OrderId => id as OrderId;
|
||||
export const createInvoiceId = (id: string): InvoiceId => id as InvoiceId;
|
||||
export const createSubscriptionId = (id: string): SubscriptionId => id as SubscriptionId;
|
||||
export const createPaymentId = (id: string): PaymentId => id as PaymentId;
|
||||
export const createCaseId = (id: string): CaseId => id as CaseId;
|
||||
export const createSessionId = (id: string): SessionId => id as SessionId;
|
||||
|
||||
export const createWhmcsClientId = (id: number): WhmcsClientId => id as WhmcsClientId;
|
||||
export const createWhmcsInvoiceId = (id: number): WhmcsInvoiceId => id as WhmcsInvoiceId;
|
||||
export const createWhmcsProductId = (id: number): WhmcsProductId => id as WhmcsProductId;
|
||||
|
||||
export const createSalesforceContactId = (id: string): SalesforceContactId =>
|
||||
id as SalesforceContactId;
|
||||
export const createSalesforceAccountId = (id: string): SalesforceAccountId =>
|
||||
id as SalesforceAccountId;
|
||||
export const createSalesforceCaseId = (id: string): SalesforceCaseId => id as SalesforceCaseId;
|
||||
|
||||
// Type guards for branded types
|
||||
export const isUserId = (id: string): id is UserId => typeof id === "string";
|
||||
export const isOrderId = (id: string): id is OrderId => typeof id === "string";
|
||||
export const isInvoiceId = (id: string): id is InvoiceId => typeof id === "string";
|
||||
export const isWhmcsClientId = (id: number): id is WhmcsClientId => typeof id === "number";
|
||||
|
||||
// Shared ISO8601 timestamp string type used for serialized dates
|
||||
export type IsoDateTimeString = string;
|
||||
|
||||
// =====================================================
|
||||
// BASE ENTITY INTERFACES
|
||||
// =====================================================
|
||||
|
||||
// Base entity interfaces for different systems
|
||||
|
||||
// Portal entities (User, etc.)
|
||||
export interface BaseEntity {
|
||||
id: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
// WHMCS entities (Invoice, Subscription, etc.)
|
||||
export interface WhmcsEntity {
|
||||
id: number;
|
||||
}
|
||||
|
||||
// Salesforce entities (SupportCase, etc.)
|
||||
export interface SalesforceEntity {
|
||||
id: string;
|
||||
createdDate: string;
|
||||
lastModifiedDate: string;
|
||||
}
|
||||
|
||||
export interface Paginated<T> {
|
||||
items: T[];
|
||||
nextCursor: string | null;
|
||||
totalCount?: number;
|
||||
}
|
||||
|
||||
// API types moved to contracts/api.ts
|
||||
|
||||
export interface IdempotencyKey {
|
||||
key: string;
|
||||
userId: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface UserMapping {
|
||||
userId: string;
|
||||
whmcsClientId: number;
|
||||
sfContactId?: string;
|
||||
sfAccountId?: string;
|
||||
createdAt?: Date;
|
||||
updatedAt?: Date;
|
||||
}
|
||||
|
||||
// Extended mapping interfaces for V2 implementation
|
||||
export interface UserIdMapping extends UserMapping {
|
||||
createdAt?: Date;
|
||||
updatedAt?: Date;
|
||||
}
|
||||
|
||||
export interface CreateMappingRequest {
|
||||
userId: string;
|
||||
whmcsClientId: number;
|
||||
sfAccountId?: string;
|
||||
}
|
||||
|
||||
export interface UpdateMappingRequest {
|
||||
whmcsClientId?: number;
|
||||
sfAccountId?: string;
|
||||
}
|
||||
|
||||
export interface MappingStats {
|
||||
totalMappings: number;
|
||||
whmcsMappings: number;
|
||||
salesforceMappings: number;
|
||||
completeMappings: number;
|
||||
orphanedMappings: number;
|
||||
}
|
||||
|
||||
// Shared address type used across BFF and Portal
|
||||
export interface Address {
|
||||
street: string | null;
|
||||
streetLine2: string | null;
|
||||
city: string | null;
|
||||
state: string | null;
|
||||
postalCode: string | null;
|
||||
country: string | null;
|
||||
}
|
||||
75
packages/domain/src/contracts/api.d.ts
vendored
75
packages/domain/src/contracts/api.d.ts
vendored
@ -1,75 +0,0 @@
|
||||
export type ApiResponse<T = unknown> = ApiSuccess<T> | ApiFailure;
|
||||
export interface ApiSuccess<T = unknown> {
|
||||
success: true;
|
||||
data: T;
|
||||
meta?: ApiMeta;
|
||||
}
|
||||
export interface ApiFailure {
|
||||
success: false;
|
||||
error: ApiError;
|
||||
meta?: ApiMeta;
|
||||
}
|
||||
export interface ApiError {
|
||||
code: string;
|
||||
message: string;
|
||||
details?: Record<string, unknown>;
|
||||
statusCode?: number;
|
||||
timestamp?: string;
|
||||
path?: string;
|
||||
}
|
||||
export interface ApiMeta {
|
||||
requestId?: string;
|
||||
timestamp?: string;
|
||||
version?: string;
|
||||
}
|
||||
export interface PaginatedResponse<T> {
|
||||
data: T[];
|
||||
pagination: {
|
||||
page: number;
|
||||
limit: number;
|
||||
total: number;
|
||||
totalPages: number;
|
||||
hasNext: boolean;
|
||||
hasPrev: boolean;
|
||||
};
|
||||
}
|
||||
export interface QueryParams extends Record<string, unknown> {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
search?: string;
|
||||
filter?: Record<string, unknown>;
|
||||
sort?: string;
|
||||
}
|
||||
export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
||||
export interface ApiRequestConfig {
|
||||
method?: HttpMethod;
|
||||
headers?: Record<string, string>;
|
||||
params?: QueryParams;
|
||||
data?: unknown;
|
||||
timeout?: number;
|
||||
retries?: number;
|
||||
cache?: boolean;
|
||||
}
|
||||
export interface ApiClient {
|
||||
get<T>(url: string, config?: ApiRequestConfig): Promise<ApiResponse<T>>;
|
||||
post<T>(url: string, data?: unknown, config?: ApiRequestConfig): Promise<ApiResponse<T>>;
|
||||
put<T>(url: string, data?: unknown, config?: ApiRequestConfig): Promise<ApiResponse<T>>;
|
||||
patch<T>(url: string, data?: unknown, config?: ApiRequestConfig): Promise<ApiResponse<T>>;
|
||||
delete<T>(url: string, config?: ApiRequestConfig): Promise<ApiResponse<T>>;
|
||||
}
|
||||
export interface ApiClientError {
|
||||
code?: string;
|
||||
message: string;
|
||||
details?: Record<string, unknown>;
|
||||
statusCode?: number;
|
||||
timestamp?: string;
|
||||
}
|
||||
export type RequestInterceptor = (config: ApiRequestConfig) => ApiRequestConfig | Promise<ApiRequestConfig>;
|
||||
export type ResponseInterceptor = <T>(response: ApiResponse<T>) => ApiResponse<T> | Promise<ApiResponse<T>>;
|
||||
export interface CrudService<T, CreateT = Partial<T>, UpdateT = Partial<T>> {
|
||||
getAll(params?: QueryParams): Promise<PaginatedResponse<T>>;
|
||||
getById(id: string): Promise<T>;
|
||||
create(data: CreateT): Promise<T>;
|
||||
update(id: string, data: UpdateT): Promise<T>;
|
||||
delete(id: string): Promise<void>;
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=api.js.map
|
||||
@ -1 +0,0 @@
|
||||
{"version":3,"file":"api.js","sourceRoot":"","sources":["api.ts"],"names":[],"mappings":""}
|
||||
@ -1,101 +0,0 @@
|
||||
// API response envelope types
|
||||
export type ApiResponse<T = unknown> = ApiSuccess<T> | ApiFailure;
|
||||
|
||||
export interface ApiSuccess<T = unknown> {
|
||||
success: true;
|
||||
data: T;
|
||||
meta?: ApiMeta;
|
||||
}
|
||||
|
||||
export interface ApiFailure {
|
||||
success: false;
|
||||
error: ApiError;
|
||||
meta?: ApiMeta;
|
||||
}
|
||||
|
||||
export interface ApiError {
|
||||
code: string;
|
||||
message: string;
|
||||
details?: Record<string, unknown>;
|
||||
statusCode?: number;
|
||||
timestamp?: string;
|
||||
path?: string;
|
||||
}
|
||||
|
||||
export interface ApiMeta {
|
||||
requestId?: string;
|
||||
timestamp?: string;
|
||||
version?: string;
|
||||
}
|
||||
|
||||
// Generic pagination interface (business contract)
|
||||
export interface PaginatedResponse<T> {
|
||||
data: T[];
|
||||
pagination: {
|
||||
page: number;
|
||||
limit: number;
|
||||
total: number;
|
||||
totalPages: number;
|
||||
hasNext: boolean;
|
||||
hasPrev: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
// Query parameters for API requests (business contract)
|
||||
export interface QueryParams extends Record<string, unknown> {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
search?: string;
|
||||
filter?: Record<string, unknown>;
|
||||
sort?: string;
|
||||
}
|
||||
|
||||
// HTTP methods (technical contract)
|
||||
export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
||||
|
||||
// API request configuration (technical contract)
|
||||
export interface ApiRequestConfig {
|
||||
method?: HttpMethod;
|
||||
headers?: Record<string, string>;
|
||||
params?: QueryParams;
|
||||
data?: unknown;
|
||||
timeout?: number;
|
||||
retries?: number;
|
||||
cache?: boolean;
|
||||
}
|
||||
|
||||
// API client interface (technical contract)
|
||||
export interface ApiClient {
|
||||
get<T>(url: string, config?: ApiRequestConfig): Promise<ApiResponse<T>>;
|
||||
post<T>(url: string, data?: unknown, config?: ApiRequestConfig): Promise<ApiResponse<T>>;
|
||||
put<T>(url: string, data?: unknown, config?: ApiRequestConfig): Promise<ApiResponse<T>>;
|
||||
patch<T>(url: string, data?: unknown, config?: ApiRequestConfig): Promise<ApiResponse<T>>;
|
||||
delete<T>(url: string, config?: ApiRequestConfig): Promise<ApiResponse<T>>;
|
||||
}
|
||||
|
||||
// API client error interface (technical contract)
|
||||
export interface ApiClientError {
|
||||
code?: string;
|
||||
message: string;
|
||||
details?: Record<string, unknown>;
|
||||
statusCode?: number;
|
||||
timestamp?: string;
|
||||
}
|
||||
|
||||
// Interceptor types (technical contract)
|
||||
export type RequestInterceptor = (
|
||||
config: ApiRequestConfig
|
||||
) => ApiRequestConfig | Promise<ApiRequestConfig>;
|
||||
|
||||
export type ResponseInterceptor = <T>(
|
||||
response: ApiResponse<T>
|
||||
) => ApiResponse<T> | Promise<ApiResponse<T>>;
|
||||
|
||||
// Generic CRUD service interface (business contract)
|
||||
export interface CrudService<T, CreateT = Partial<T>, UpdateT = Partial<T>> {
|
||||
getAll(params?: QueryParams): Promise<PaginatedResponse<T>>;
|
||||
getById(id: string): Promise<T>;
|
||||
create(data: CreateT): Promise<T>;
|
||||
update(id: string, data: UpdateT): Promise<T>;
|
||||
delete(id: string): Promise<void>;
|
||||
}
|
||||
60
packages/domain/src/contracts/catalog.d.ts
vendored
60
packages/domain/src/contracts/catalog.d.ts
vendored
@ -1,60 +0,0 @@
|
||||
export interface CatalogProductBase {
|
||||
id: string;
|
||||
sku: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
displayOrder?: number;
|
||||
billingCycle?: string;
|
||||
monthlyPrice?: number;
|
||||
oneTimePrice?: number;
|
||||
unitPrice?: number;
|
||||
}
|
||||
export interface InternetCatalogProduct extends CatalogProductBase {
|
||||
internetPlanTier?: string;
|
||||
internetOfferingType?: string;
|
||||
features?: string[];
|
||||
}
|
||||
export interface InternetPlanTemplate {
|
||||
tierDescription: string;
|
||||
description?: string;
|
||||
features?: string[];
|
||||
}
|
||||
export interface InternetPlanCatalogItem extends InternetCatalogProduct {
|
||||
catalogMetadata?: {
|
||||
tierDescription?: string;
|
||||
features?: string[];
|
||||
isRecommended?: boolean;
|
||||
};
|
||||
}
|
||||
export interface InternetInstallationCatalogItem extends InternetCatalogProduct {
|
||||
catalogMetadata?: {
|
||||
installationTerm: "One-time" | "12-Month" | "24-Month";
|
||||
};
|
||||
}
|
||||
export interface InternetAddonCatalogItem extends InternetCatalogProduct {
|
||||
isBundledAddon?: boolean;
|
||||
bundledAddonId?: string;
|
||||
}
|
||||
export interface SimCatalogProduct extends CatalogProductBase {
|
||||
simDataSize?: string;
|
||||
simPlanType?: string;
|
||||
simHasFamilyDiscount?: boolean;
|
||||
isBundledAddon?: boolean;
|
||||
bundledAddonId?: string;
|
||||
}
|
||||
export interface SimActivationFeeCatalogItem extends SimCatalogProduct {
|
||||
catalogMetadata?: {
|
||||
isDefault: boolean;
|
||||
};
|
||||
}
|
||||
export interface VpnCatalogProduct extends CatalogProductBase {
|
||||
vpnRegion?: string;
|
||||
}
|
||||
export interface CatalogPricebookEntry {
|
||||
id?: string;
|
||||
name?: string;
|
||||
unitPrice?: number;
|
||||
pricebook2Id?: string;
|
||||
product2Id?: string;
|
||||
isActive?: boolean;
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=catalog.js.map
|
||||
@ -1 +0,0 @@
|
||||
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["catalog.ts"],"names":[],"mappings":""}
|
||||
@ -1,70 +0,0 @@
|
||||
// Shared catalog contracts consumed by both BFF and Portal
|
||||
|
||||
export interface CatalogProductBase {
|
||||
id: string;
|
||||
sku: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
displayOrder?: number;
|
||||
billingCycle?: string;
|
||||
monthlyPrice?: number;
|
||||
oneTimePrice?: number;
|
||||
unitPrice?: number;
|
||||
}
|
||||
|
||||
export interface InternetCatalogProduct extends CatalogProductBase {
|
||||
internetPlanTier?: string;
|
||||
internetOfferingType?: string;
|
||||
features?: string[];
|
||||
}
|
||||
|
||||
export interface InternetPlanTemplate {
|
||||
tierDescription: string;
|
||||
description?: string;
|
||||
features?: string[];
|
||||
}
|
||||
|
||||
export interface InternetPlanCatalogItem extends InternetCatalogProduct {
|
||||
catalogMetadata?: {
|
||||
tierDescription?: string;
|
||||
features?: string[];
|
||||
isRecommended?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export interface InternetInstallationCatalogItem extends InternetCatalogProduct {
|
||||
catalogMetadata?: {
|
||||
installationTerm: "One-time" | "12-Month" | "24-Month";
|
||||
};
|
||||
}
|
||||
|
||||
export interface InternetAddonCatalogItem extends InternetCatalogProduct {
|
||||
isBundledAddon?: boolean;
|
||||
bundledAddonId?: string;
|
||||
}
|
||||
|
||||
export interface SimCatalogProduct extends CatalogProductBase {
|
||||
simDataSize?: string;
|
||||
simPlanType?: string;
|
||||
simHasFamilyDiscount?: boolean;
|
||||
isBundledAddon?: boolean;
|
||||
bundledAddonId?: string;
|
||||
}
|
||||
|
||||
export interface SimActivationFeeCatalogItem extends SimCatalogProduct {
|
||||
catalogMetadata?: {
|
||||
isDefault: boolean;
|
||||
};
|
||||
}
|
||||
export interface VpnCatalogProduct extends CatalogProductBase {
|
||||
vpnRegion?: string;
|
||||
}
|
||||
|
||||
export interface CatalogPricebookEntry {
|
||||
id?: string;
|
||||
name?: string;
|
||||
unitPrice?: number;
|
||||
pricebook2Id?: string;
|
||||
product2Id?: string;
|
||||
isActive?: boolean;
|
||||
}
|
||||
3
packages/domain/src/contracts/index.d.ts
vendored
3
packages/domain/src/contracts/index.d.ts
vendored
@ -1,3 +0,0 @@
|
||||
export * from "./api";
|
||||
export * from "./catalog";
|
||||
export * from "./salesforce";
|
||||
@ -1,20 +0,0 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./api"), exports);
|
||||
__exportStar(require("./catalog"), exports);
|
||||
__exportStar(require("./salesforce"), exports);
|
||||
//# sourceMappingURL=index.js.map
|
||||
@ -1 +0,0 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,wCAAsB;AACtB,4CAA0B;AAC1B,+CAA6B"}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user