Add lookup tables, payment methods, tax exemptions, and processor link APIs
Replace unit_status and item_condition pgEnums with company-scoped lookup tables that support custom values. Add account_payment_method table, tax_exemption table with approve/revoke workflow, and CRUD routes for processor links. Validate inventory unit status/condition against lookup tables at service layer.
This commit is contained in:
@@ -3,6 +3,12 @@ import { z } from 'zod'
|
||||
export const BillingMode = z.enum(['consolidated', 'split'])
|
||||
export type BillingMode = z.infer<typeof BillingMode>
|
||||
|
||||
export const PaymentProcessor = z.enum(['stripe', 'global_payments'])
|
||||
export type PaymentProcessor = z.infer<typeof PaymentProcessor>
|
||||
|
||||
export const TaxExemptStatus = z.enum(['none', 'pending', 'approved'])
|
||||
export type TaxExemptStatus = z.infer<typeof TaxExemptStatus>
|
||||
|
||||
export const AccountCreateSchema = z.object({
|
||||
name: z.string().min(1).max(255),
|
||||
email: z.string().email().optional(),
|
||||
@@ -40,3 +46,76 @@ export type MemberUpdateInput = z.infer<typeof MemberUpdateSchema>
|
||||
export const AccountSearchSchema = z.object({
|
||||
q: z.string().min(1).max(255),
|
||||
})
|
||||
|
||||
// --- Account Processor Link ---
|
||||
|
||||
export const ProcessorLinkCreateSchema = z.object({
|
||||
accountId: z.string().uuid(),
|
||||
processor: PaymentProcessor,
|
||||
processorCustomerId: z.string().min(1).max(255),
|
||||
})
|
||||
export type ProcessorLinkCreateInput = z.infer<typeof ProcessorLinkCreateSchema>
|
||||
|
||||
export const ProcessorLinkUpdateSchema = z.object({
|
||||
isActive: z.boolean().optional(),
|
||||
})
|
||||
export type ProcessorLinkUpdateInput = z.infer<typeof ProcessorLinkUpdateSchema>
|
||||
|
||||
// --- Account Payment Method ---
|
||||
|
||||
export const PaymentMethodCreateSchema = z.object({
|
||||
accountId: z.string().uuid(),
|
||||
processor: PaymentProcessor,
|
||||
processorPaymentMethodId: z.string().min(1).max(255),
|
||||
cardBrand: z.string().max(50).optional(),
|
||||
lastFour: z.string().length(4).optional(),
|
||||
expMonth: z.number().int().min(1).max(12).optional(),
|
||||
expYear: z.number().int().min(2000).max(2100).optional(),
|
||||
isDefault: z.boolean().default(false),
|
||||
})
|
||||
export type PaymentMethodCreateInput = z.infer<typeof PaymentMethodCreateSchema>
|
||||
|
||||
export const PaymentMethodUpdateSchema = z.object({
|
||||
isDefault: z.boolean().optional(),
|
||||
requiresUpdate: z.boolean().optional(),
|
||||
})
|
||||
export type PaymentMethodUpdateInput = z.infer<typeof PaymentMethodUpdateSchema>
|
||||
|
||||
// --- Tax Exemption ---
|
||||
|
||||
export const TaxExemptionCreateSchema = z.object({
|
||||
accountId: z.string().uuid(),
|
||||
certificateNumber: z.string().min(1).max(255),
|
||||
certificateType: z.string().max(100).optional(),
|
||||
issuingState: z.string().length(2).optional(),
|
||||
expiresAt: z.string().date().optional(),
|
||||
notes: z.string().optional(),
|
||||
})
|
||||
export type TaxExemptionCreateInput = z.infer<typeof TaxExemptionCreateSchema>
|
||||
|
||||
export const TaxExemptionUpdateSchema = z.object({
|
||||
certificateNumber: z.string().min(1).max(255).optional(),
|
||||
certificateType: z.string().max(100).optional(),
|
||||
issuingState: z.string().length(2).optional(),
|
||||
expiresAt: z.string().date().optional(),
|
||||
notes: z.string().optional(),
|
||||
})
|
||||
export type TaxExemptionUpdateInput = z.infer<typeof TaxExemptionUpdateSchema>
|
||||
|
||||
// --- Lookup Tables ---
|
||||
|
||||
export const LookupCreateSchema = z.object({
|
||||
name: z.string().min(1).max(100),
|
||||
slug: z.string().min(1).max(100).regex(/^[a-z0-9_]+$/, 'Slug must be lowercase alphanumeric with underscores'),
|
||||
description: z.string().optional(),
|
||||
sortOrder: z.number().int().default(0),
|
||||
})
|
||||
export type LookupCreateInput = z.infer<typeof LookupCreateSchema>
|
||||
|
||||
export const LookupUpdateSchema = z.object({
|
||||
name: z.string().min(1).max(100).optional(),
|
||||
description: z.string().optional(),
|
||||
sortOrder: z.number().int().optional(),
|
||||
isActive: z.boolean().optional(),
|
||||
})
|
||||
export type LookupUpdateInput = z.infer<typeof LookupUpdateSchema>
|
||||
|
||||
@@ -6,17 +6,35 @@ export type { RegisterInput, LoginInput } from './auth.schema.js'
|
||||
|
||||
export {
|
||||
BillingMode,
|
||||
PaymentProcessor,
|
||||
TaxExemptStatus,
|
||||
AccountCreateSchema,
|
||||
AccountUpdateSchema,
|
||||
MemberCreateSchema,
|
||||
MemberUpdateSchema,
|
||||
AccountSearchSchema,
|
||||
ProcessorLinkCreateSchema,
|
||||
ProcessorLinkUpdateSchema,
|
||||
PaymentMethodCreateSchema,
|
||||
PaymentMethodUpdateSchema,
|
||||
TaxExemptionCreateSchema,
|
||||
TaxExemptionUpdateSchema,
|
||||
LookupCreateSchema,
|
||||
LookupUpdateSchema,
|
||||
} from './account.schema.js'
|
||||
export type {
|
||||
AccountCreateInput,
|
||||
AccountUpdateInput,
|
||||
MemberCreateInput,
|
||||
MemberUpdateInput,
|
||||
ProcessorLinkCreateInput,
|
||||
ProcessorLinkUpdateInput,
|
||||
PaymentMethodCreateInput,
|
||||
PaymentMethodUpdateInput,
|
||||
TaxExemptionCreateInput,
|
||||
TaxExemptionUpdateInput,
|
||||
LookupCreateInput,
|
||||
LookupUpdateInput,
|
||||
} from './account.schema.js'
|
||||
|
||||
export {
|
||||
@@ -26,6 +44,8 @@ export {
|
||||
SupplierUpdateSchema,
|
||||
ItemCondition,
|
||||
UnitStatus,
|
||||
SystemItemCondition,
|
||||
SystemUnitStatus,
|
||||
ProductCreateSchema,
|
||||
ProductUpdateSchema,
|
||||
ProductSearchSchema,
|
||||
|
||||
@@ -26,8 +26,23 @@ export type SupplierCreateInput = z.infer<typeof SupplierCreateSchema>
|
||||
export const SupplierUpdateSchema = SupplierCreateSchema.partial()
|
||||
export type SupplierUpdateInput = z.infer<typeof SupplierUpdateSchema>
|
||||
|
||||
export const ItemCondition = z.enum(['new', 'excellent', 'good', 'fair', 'poor'])
|
||||
export const UnitStatus = z.enum(['available', 'sold', 'rented', 'in_repair', 'retired'])
|
||||
// System slugs — used for code-level business logic references.
|
||||
// Actual valid values are stored in lookup tables and are company-configurable.
|
||||
export const SystemItemCondition = z.enum(['new', 'excellent', 'good', 'fair', 'poor'])
|
||||
export const SystemUnitStatus = z.enum([
|
||||
'available',
|
||||
'sold',
|
||||
'rented',
|
||||
'on_trial',
|
||||
'in_repair',
|
||||
'layaway',
|
||||
'lost',
|
||||
'retired',
|
||||
])
|
||||
|
||||
// API validation accepts any string slug (validated against lookup table at service layer)
|
||||
export const ItemCondition = z.string().min(1).max(100)
|
||||
export const UnitStatus = z.string().min(1).max(100)
|
||||
|
||||
export const ProductCreateSchema = z.object({
|
||||
sku: z.string().max(100).optional(),
|
||||
|
||||
Reference in New Issue
Block a user