OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-booking / scripts / seed.js

155 lines · javascript ref:
#!/usr/bin/env bare

/**
 * Seed script — populate dev data.
 * Usage: bare scripts/seed.js [--storage=path]
 */

await import('bare-node-runtime/global')

import path from 'bare-path'
import os from 'bare-os'
import Corestore from 'corestore'
import Hyperbee from 'hyperbee'
import crypto from 'bare-crypto'

const args = process.argv.slice(2)
let storage = path.join(os.homedir(), '.config', 'hyper-booking', 'data')
for (const arg of args) {
  if (arg.startsWith('--storage=')) storage = arg.split('=')[1]
}

console.log('Seeding into:', storage)

const store = new Corestore(storage)
const core = store.get({ name: 'registry' })
const db = new Hyperbee(core, { keyEncoding: 'utf-8', valueEncoding: 'json' })
await db.ready()

function genId (prefix) {
  return prefix + '_' + crypto.randomBytes(12).toString('hex')
}

// Create test provider
const providerId = genId('prov')
const provider = {
  id: providerId,
  slug: 'alexis-mattos',
  displayName: 'Alexis Mattos',
  bio: 'Holistic health coach specializing in stress management, nutrition, and sustainable wellness. I believe in meeting you where you are and building a personalized plan that fits your life.\n\nWith over 8 years of experience in integrative health coaching, I help clients achieve lasting change through science-backed strategies and compassionate support.',
  timezone: 'America/New_York',
  specialties: ['Health Coaching', 'Stress Management', 'Nutrition', 'Wellness'],
  socialLinks: {},
  photo: null,
  accentColor: '#c4a265',
  active: true,
  userId: 'admin',
  createdAt: Date.now()
}

// Create packages (mirroring the Paperbell screenshots)
const pkgDiscovery = {
  id: genId('pkg'),
  providerId,
  name: 'Free Discovery Call',
  type: 'discovery',
  description: 'A low-pressure conversation to talk through what\'s been on your mind and explore whether coaching could support you right now.',
  sessionDuration: 15,
  sessionCount: 1,
  price: 0,
  currency: 'USD',
  active: true,
  createdAt: Date.now()
}

const pkgSingle = {
  id: genId('pkg'),
  providerId,
  name: '30-Minute Health Coaching Session',
  type: 'single',
  description: 'One more step toward the healthiest version of you.',
  sessionDuration: 30,
  sessionCount: 1,
  price: 7500, // $75
  currency: 'USD',
  active: true,
  createdAt: Date.now()
}

const pkg60 = {
  id: genId('pkg'),
  providerId,
  name: '60-Minute Deep Dive Session',
  type: 'single',
  description: 'A full hour to go deep on your health goals, identify blockers, and create an actionable plan.',
  sessionDuration: 60,
  sessionCount: 1,
  price: 12000, // $120
  currency: 'USD',
  active: true,
  createdAt: Date.now()
}

const pkgBundle = {
  id: genId('pkg'),
  providerId,
  name: '6-Session Coaching Package',
  type: 'bundle',
  description: 'Comprehensive coaching for lasting change. Six 60-minute sessions to work through your goals with accountability and support.',
  sessionDuration: 60,
  sessionCount: 6,
  price: 60000, // $600
  currency: 'USD',
  discountFullPay: 10,
  installments: 3,
  active: true,
  createdAt: Date.now()
}

// Set availability (Mon-Fri, typical coaching schedule)
const availability = {
  providerId,
  timezone: 'America/New_York',
  weekly: {
    monday: [{ start: '09:00', end: '12:00' }, { start: '14:00', end: '17:00' }],
    tuesday: [{ start: '09:00', end: '17:00' }],
    wednesday: [{ start: '09:00', end: '12:00' }],
    thursday: [{ start: '10:00', end: '18:00' }],
    friday: [{ start: '09:00', end: '15:00' }],
    saturday: [],
    sunday: []
  },
  bufferMinutes: 15,
  advanceBooking: { minHours: 24, maxDays: 60 },
  cancellation: { windowHours: 24, refundPolicy: 'full' },
  reschedule: { windowHours: 24, maxPerBooking: 2 },
  noShow: { penalty: 'forfeit' }
}

// Write everything
const batch = db.batch()

await batch.put(`provider:${providerId}`, provider)
await batch.put(`provider-by-slug:${provider.slug}`, providerId)

for (const pkg of [pkgDiscovery, pkgSingle, pkg60, pkgBundle]) {
  await batch.put(`package:${providerId}:${pkg.id}`, pkg)
  await batch.put(`package-detail:${pkg.id}`, pkg)
}

await batch.put(`availability:${providerId}`, availability)
await batch.put('meta:initialized', { at: Date.now(), version: '0.1.0' })

await batch.flush()

console.log('Seeded:')
console.log(`  Provider: ${provider.displayName} (/${provider.slug})`)
console.log(`  Packages: ${[pkgDiscovery, pkgSingle, pkg60, pkgBundle].map(p => p.name).join(', ')}`)
console.log(`  Availability: Mon-Fri`)
console.log('')
console.log(`Start server: bare index.js serve`)
console.log(`Visit: http://localhost:4050/${provider.slug}`)

await store.close()
process.exit(0)