chore: Remove unused billing-related collections, types, and utility modules

- Drop `customers` collection and associated types (`types/index.ts`, `payload.ts`)
- Remove generated `payload-types.ts` file
- Clean up unused exports and dependencies across modules
- Streamline codebase by eliminating redundant billing logic
This commit is contained in:
2025-09-15 23:14:25 +02:00
parent 28e9e8d208
commit f17b4c064e
11 changed files with 338 additions and 1378 deletions

View File

@@ -1,149 +0,0 @@
import type { CollectionConfig } from 'payload'
import type {
AccessArgs,
CollectionAfterChangeHook,
CollectionBeforeChangeHook,
CustomerData,
CustomerDocument
} from '../types/payload'
export function createCustomersCollection(slug: string = 'customers'): CollectionConfig {
return {
slug,
access: {
create: ({ req: { user } }: AccessArgs) => !!user,
delete: ({ req: { user } }: AccessArgs) => !!user,
read: ({ req: { user } }: AccessArgs) => !!user,
update: ({ req: { user } }: AccessArgs) => !!user,
},
admin: {
defaultColumns: ['email', 'name', 'createdAt'],
group: 'Billing',
useAsTitle: 'email',
},
fields: [
{
name: 'email',
type: 'email',
admin: {
description: 'Customer email address',
},
index: true,
unique: true,
},
{
name: 'name',
type: 'text',
admin: {
description: 'Customer full name',
},
},
{
name: 'phone',
type: 'text',
admin: {
description: 'Customer phone number',
},
},
{
name: 'address',
type: 'group',
fields: [
{
name: 'line1',
type: 'text',
label: 'Address Line 1',
},
{
name: 'line2',
type: 'text',
label: 'Address Line 2',
},
{
name: 'city',
type: 'text',
label: 'City',
},
{
name: 'state',
type: 'text',
label: 'State/Province',
},
{
name: 'postalCode',
type: 'text',
label: 'Postal Code',
},
{
name: 'country',
type: 'text',
admin: {
description: 'ISO 3166-1 alpha-2 country code',
},
label: 'Country',
maxLength: 2,
},
],
},
{
name: 'providerIds',
type: 'json',
admin: {
description: 'Customer IDs from payment providers',
readOnly: true,
},
},
{
name: 'metadata',
type: 'json',
admin: {
description: 'Additional customer metadata',
},
},
{
name: 'payments',
type: 'relationship',
admin: {
description: 'Customer payments',
readOnly: true,
},
hasMany: true,
relationTo: 'payments',
},
{
name: 'invoices',
type: 'relationship',
admin: {
description: 'Customer invoices',
readOnly: true,
},
hasMany: true,
relationTo: 'invoices',
},
],
hooks: {
afterChange: [
({ doc, operation, req }: CollectionAfterChangeHook<CustomerDocument>) => {
if (operation === 'create') {
req.payload.logger.info(`Customer created: ${doc.id} (${doc.email})`)
}
},
],
beforeChange: [
({ data, operation }: CollectionBeforeChangeHook<CustomerData>) => {
if (operation === 'create' || operation === 'update') {
// Normalize country code
if (data.address?.country) {
data.address.country = data.address.country.toUpperCase()
if (!/^[A-Z]{2}$/.test(data.address.country)) {
throw new Error('Country must be a 2-letter ISO code')
}
}
}
},
],
},
timestamps: true,
}
}

View File

@@ -1,15 +1,12 @@
import type { CollectionConfig } from 'payload'
import type {
import {
AccessArgs,
CollectionAfterChangeHook,
CollectionBeforeChangeHook,
CollectionBeforeValidateHook,
InvoiceData,
InvoiceDocument,
InvoiceItemData
} from '../types/payload'
import type { CustomerInfoExtractor } from '../types'
CollectionConfig,
} from 'payload'
import { CustomerInfoExtractor } from '@/plugin/config'
import { Invoice } from '@/plugin/types'
export function createInvoicesCollection(
slug: string = 'invoices',
@@ -281,7 +278,7 @@ export function createInvoicesCollection(
name: 'paidAt',
type: 'date',
admin: {
condition: (data: InvoiceData) => data.status === 'paid',
condition: (data) => data.status === 'paid',
readOnly: true,
},
},
@@ -289,7 +286,7 @@ export function createInvoicesCollection(
name: 'payment',
type: 'relationship',
admin: {
condition: (data: InvoiceData) => data.status === 'paid',
condition: (data) => data.status === 'paid',
position: 'sidebar',
},
relationTo: 'payments',
@@ -311,14 +308,14 @@ export function createInvoicesCollection(
],
hooks: {
afterChange: [
({ doc, operation, req }: CollectionAfterChangeHook<InvoiceDocument>) => {
({ doc, operation, req }) => {
if (operation === 'create') {
req.payload.logger.info(`Invoice created: ${doc.number}`)
}
},
],
] satisfies CollectionAfterChangeHook<Invoice>[],
beforeChange: [
async ({ data, operation, req, originalDoc }: CollectionBeforeChangeHook<InvoiceData>) => {
async ({ data, operation, req, originalDoc }) => {
// Sync customer info from relationship if extractor is provided
if (customerCollectionSlug && customerInfoExtractor && data.customer) {
// Check if customer changed or this is a new invoice
@@ -329,7 +326,7 @@ export function createInvoicesCollection(
try {
// Fetch the customer data
const customer = await req.payload.findByID({
collection: customerCollectionSlug,
collection: customerCollectionSlug as any,
id: data.customer,
})
@@ -383,9 +380,9 @@ export function createInvoicesCollection(
data.paidAt = new Date().toISOString()
}
},
],
] satisfies CollectionBeforeChangeHook<Invoice>[],
beforeValidate: [
({ data }: CollectionBeforeValidateHook<InvoiceData>) => {
({ data }) => {
if (!data) return
// If using extractor, customer relationship is required
@@ -406,14 +403,14 @@ export function createInvoicesCollection(
if (data && data.items && Array.isArray(data.items)) {
// Calculate totals for each line item
data.items = data.items.map((item: InvoiceItemData) => ({
data.items = data.items.map((item) => ({
...item,
totalAmount: (item.quantity || 0) * (item.unitAmount || 0),
}))
// Calculate subtotal
data.subtotal = data.items.reduce(
(sum: number, item: InvoiceItemData) => sum + (item.totalAmount || 0),
(sum: number, item) => sum + (item.totalAmount || 0),
0
)
@@ -421,8 +418,8 @@ export function createInvoicesCollection(
data.amount = (data.subtotal || 0) + (data.taxAmount || 0)
}
},
],
] satisfies CollectionBeforeValidateHook<Invoice>[],
},
timestamps: true,
}
}
}

View File

@@ -1,12 +1,5 @@
import type { CollectionConfig } from 'payload'
import type {
AccessArgs,
CollectionAfterChangeHook,
CollectionBeforeChangeHook,
PaymentData,
PaymentDocument
} from '../types/payload'
import { AccessArgs, CollectionAfterChangeHook, CollectionBeforeChangeHook, CollectionConfig } from 'payload'
import { Payment } from '@/plugin/types'
export function createPaymentsCollection(slug: string = 'payments'): CollectionConfig {
return {
@@ -131,21 +124,14 @@ export function createPaymentsCollection(slug: string = 'payments'): CollectionC
},
],
hooks: {
afterChange: [
({ doc, operation, req }: CollectionAfterChangeHook<PaymentDocument>) => {
if (operation === 'create') {
req.payload.logger.info(`Payment created: ${doc.id} (${doc.provider})`)
}
},
],
beforeChange: [
({ data, operation }: CollectionBeforeChangeHook<PaymentData>) => {
({ data, operation }) => {
if (operation === 'create') {
// Validate amount format
if (data.amount && !Number.isInteger(data.amount)) {
throw new Error('Amount must be an integer (in cents)')
}
// Validate currency format
if (data.currency) {
data.currency = data.currency.toUpperCase()
@@ -155,8 +141,8 @@ export function createPaymentsCollection(slug: string = 'payments'): CollectionC
}
}
},
],
] satisfies CollectionBeforeChangeHook<Payment>[],
},
timestamps: true,
}
}
}