Development
Guide for contributors and local development of the plugin itself.
Guide for contributors and local development of the plugin itself.
Prerequisites
- Node.js
^18.20.2or>=20.9.0 - pnpm
^9or^10
Commands
pnpm dev # Start dev server (Next.js + in-memory MongoDB)
pnpm build # Build for distribution
pnpm test:int # Run integration tests (Vitest)
pnpm test:e2e # Run E2E tests (Playwright, requires dev server)
pnpm test # Both test suites
pnpm lint # ESLint check
pnpm lint:fix # ESLint auto-fix
pnpm dev:generate-types # Regenerate payload-types.ts after schema changes
pnpm dev:generate-importmap # Regenerate import map after adding componentsRun a single test by pattern: pnpm vitest -t "conflict detection"
Project Structure
src/
index.ts # Public API: re-exports plugin + types
plugin.ts # Main plugin factory function
types.ts # All TypeScript types + DEFAULT_STATUS_MACHINE
defaults.ts # Default config values + resolveConfig()
collections/
Services.ts # Service definitions (name, duration, durationType, price, buffers)
Resources.ts # Resources (quantity, capacityMode, timezone)
Schedules.ts # Availability schedules (recurring/manual + exceptions)
Reservations.ts # Bookings with hooks, guestCount, items, idempotencyKey
Customers.ts # Standalone customer auth collection
hooks/reservations/
checkIdempotency.ts # Duplicate submission prevention
calculateEndTime.ts # Auto end time from service duration
validateConflicts.ts # Double-booking prevention
validateStatusTransition.ts # Status machine enforcement
validateCancellation.ts # Cancellation notice period
onStatusChange.ts # afterChange hook — fires plugin hook callbacks
services/
AvailabilityService.ts # computeEndTime, checkAvailability, getAvailableSlots
endpoints/
checkAvailability.ts # GET /api/reserve/availability
getSlots.ts # GET /api/reserve/slots
createBooking.ts # POST /api/reserve/book
cancelBooking.ts # POST /api/reserve/cancel
customerSearch.ts # GET /api/reserve/customers
utilities/
slotUtils.ts # addMinutes, doRangesOverlap, computeBlockedWindow, hoursUntil
scheduleUtils.ts # resolveScheduleForDate, combineDateAndTime, etc.
resolveReservationItems.ts # Normalizes reservation data into ResolvedItem[]
components/
CalendarView/ # Client: month/week/day calendar
CustomerField/ # Client: rich customer search field
DashboardWidget/ # RSC: today's reservation stats
AvailabilityOverview/ # Client: weekly resource grid
exports/
client.ts # CalendarView, AvailabilityOverview, CustomerField
rsc.ts # DashboardWidgetServer
dev/
payload.config.ts # Dev Payload config (MongoDB Memory Server)
seed.ts # Sample salon data
int.spec.ts # Vitest integration tests
e2e.spec.ts # Playwright E2E testsKey Conventions
- ESM throughout —
"type": "module"in package.json. Use.jsextensions in import paths even for TypeScript files. - Prettier — single quotes, no semicolons, trailing commas, 100-char line width.
- TypeScript strict mode — types-only emit via
tsc; actual transpilation via SWC. - Peer dependencies — all peer dependencies (payload, react, next) are devDependencies — peer dependencies are
payload ^3.79.0,@payloadcms/ui ^3.79.0,@payloadcms/translations ^3.79.0. - Object property ordering — alphabetically ordered (enforced by
perfectionist/sort-objects). Note:idis treated as a top group and sorts before all other keys.