Services Architecture
Background workers, Inngest events, and external integrations.
change-stream-worker
A long-running Node service that monitors PostgreSQL for changes via LISTEN/NOTIFY. When rows in FolioPlant or Folio are inserted, updated, or deleted, it sends events to Inngest for processing (e.g. search indexing).
- Located in
apps/change-stream-worker - Deployed on Railway
- Requires database triggers:
enable-database-notifications.sql - Health check at
/health
Flow: PostgreSQL LISTEN → Change Stream Worker → Inngest Event → Background Job
render-worker
Express service that renders signage to PDF or ZIP. The dashboard sends a sign render request via Inngest; an Inngest function calls the render-worker HTTP endpoint. Output is uploaded to Vercel Blob.
- Located in
apps/render-worker - Deployed on Railway
- Endpoint:
POST /render(jobId, printSignUrl, templateType, etc.) - Health check at
/health - Dashboard configures the worker URL via environment variables
Inngest Events
Event types defined in packages/events/src/inngest.ts:
ticket/create— Support ticket createdsurvey/complete— User survey completedinvite/create— Invitation createdonboarding/complete— User onboarding completedidentification/suggestion/plantFound— Plant suggestion founduser/create— User createdidentification/create— Identification createdplant/create— Plant createdfolioplant/insert,folioplant/update,folioplant/delete— From change-streamfolio/insert,folio/update,folio/delete— From change-streamsign/render/requested— Sign render job
External Services
- Algolia — Plant and folio search
- Vercel Blob — Media storage, signage assets, rendered PDFs
- Resend — Transactional email
- Stripe — Payments, subscriptions
- Clerk — Authentication
- Sentry — Error monitoring
- Plant.id / Brave / Trefle — Plant identification, search
plantfolio_mobile
Flutter mobile app in apps/plantfolio_mobile. Consumes shared backend via API/client logic.