v4.0.5
Component architecture - Reorganise src/lib/components into pages/, sections/, ui/ subdirectories and update all imports across routes and tests. Owner admin dashboard (+2k lines) - Scheduled welcome-pack emails: durable queue with cancel/reschedule and a background sender loop (SCHEDULED_CHECK_INTERVAL_SECONDS, default 60s). - Custom welcome-pack subject line, preview recipients, and client BCC. - Add-client, edit client profile, and reset-onboarding flows. - "View as client" onboarding preview (owner impersonation, dry-run submit). - Tabbed owner welcome route (/owner/welcome/[[tab]]). MYOB integration - New mail_api/myob.py: create new clients as MYOB AccountRight customer contacts. Disabled until all MYOB_* env vars are set (no-op otherwise). Onboarding - New "Does your dog resource guard?" Yes/No question in the Behaviour step. - Persist vetAddress, flea/tick, and pet-insurance fields server-side. Misc - vite config, new hooks.ts, responsive CSS tweaks, deploy/docker config, mail-api README and start-dev.ps1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -41,9 +41,13 @@ class OnboardingSubmission(BaseSubmission):
|
||||
medicalNotes: str = ""
|
||||
accessInstructions: str = ""
|
||||
vetName: str
|
||||
vetAddress: str
|
||||
vetPhone: str
|
||||
emergencyContactName: str
|
||||
emergencyContactPhone: str
|
||||
regularFleaTickTreatment: str = ""
|
||||
petInsurance: str = ""
|
||||
petInsuranceOwnerExpenseAccepted: bool = False
|
||||
councilRegistrationConfirmed: bool = False
|
||||
vaccinationsConfirmed: bool = False
|
||||
emergencyVetConsent: bool = False
|
||||
@@ -54,15 +58,33 @@ class OnboardingSubmission(BaseSubmission):
|
||||
|
||||
class WelcomePackEmailRequest(BaseModel):
|
||||
email: EmailStr
|
||||
# Owner-set subject line. Defaults to "Goodwalk Onboarding - <Dog Name>" when
|
||||
# blank (resolved server-side so scheduled sends keep a sensible subject too).
|
||||
subject: str = ""
|
||||
serviceType: str
|
||||
priceDetails: str
|
||||
startDate: str
|
||||
preview: bool = False
|
||||
previewRecipients: list[EmailStr] = []
|
||||
# ISO 8601 local datetime (e.g. "2026-06-20T14:30"). When set on a non-preview
|
||||
# request, the welcome email is queued for reliable delivery at that time
|
||||
# instead of being sent immediately.
|
||||
scheduledFor: str | None = None
|
||||
|
||||
|
||||
class ScheduledEmailCancelRequest(BaseModel):
|
||||
id: str
|
||||
|
||||
|
||||
class ScheduledEmailRescheduleRequest(BaseModel):
|
||||
id: str
|
||||
scheduledFor: str
|
||||
|
||||
|
||||
class BirthdayEmailRequest(BaseModel):
|
||||
email: EmailStr
|
||||
preview: bool = False
|
||||
previewRecipients: list[EmailStr] = []
|
||||
|
||||
|
||||
class BirthdayAutoSendRequest(BaseModel):
|
||||
@@ -81,6 +103,42 @@ class ClientStatusUpdate(BaseModel):
|
||||
reason: str = ""
|
||||
|
||||
|
||||
class ClientProfileUpdate(BaseModel):
|
||||
email: EmailStr
|
||||
nextEmail: EmailStr
|
||||
fullName: str
|
||||
phone: str = ""
|
||||
address: str = ""
|
||||
dogName: str
|
||||
|
||||
|
||||
class ResetOnboardingRequest(BaseModel):
|
||||
"""Owner-initiated reset: keep the client's saved details but mark their
|
||||
onboarding incomplete so they can sign in and complete the new form
|
||||
(used for clients imported from the legacy Gravity Forms data)."""
|
||||
|
||||
email: EmailStr
|
||||
|
||||
|
||||
class NewClientRequest(BaseModel):
|
||||
"""Owner-initiated client creation (e.g. leads from Instagram / Facebook
|
||||
that never came through the public enquiry form). Registers the email so
|
||||
the client can access the onboarding form, and seeds a profile."""
|
||||
|
||||
email: EmailStr
|
||||
fullName: str
|
||||
phone: str = ""
|
||||
address: str = ""
|
||||
dogName: str = ""
|
||||
dogBreed: str = ""
|
||||
# Where the client came from, e.g. "Instagram", "Facebook", "Referral".
|
||||
source: str = ""
|
||||
# When true (and the MYOB integration is configured), also create the client
|
||||
# as a customer contact in MYOB. Non-fatal: a MYOB failure never blocks the
|
||||
# local client from being created.
|
||||
createInMyob: bool = False
|
||||
|
||||
|
||||
class ContractSubmission(BaseSubmission):
|
||||
address: str
|
||||
dogName: str
|
||||
@@ -126,3 +184,4 @@ class SendMessageRequest(BaseModel):
|
||||
fontId: str = "system"
|
||||
recipients: list[EmailStr] = []
|
||||
preview: bool = False
|
||||
previewRecipients: list[EmailStr] = []
|
||||
|
||||
Reference in New Issue
Block a user