Airtable Implementation Packet
Date: March 9, 2026 Purpose: keep the Airtable cutover plan current as execution moves from discovery into validation and remaining implementation
Goal
Track the highest-value Airtable-backed workflows and the remaining implementation gaps:
- Parent intake submissions
- Doula application submissions
- Doula availability responses and client-visible matches
- Interview persistence
- Payment ledger persistence
Critical Reality Check
The repo currently has two conflicting Airtable models:
-
AIRTABLE-SCHEMA.md- old documentation
- describes a generic single-base, 9-table design
-
airtable.ts- current code reality
- expects a multi-base setup:
AIRTABLE_PARENTS_BASE_IDAIRTABLE_DOULAS_BASE_IDAIRTABLE_PRODUCTS_BASE_IDAIRTABLE_MARKETING_BASE_IDAIRTABLE_ADMIN_BASE_ID
- currently targets these real table names:
Parent Intake FormsParent-Doula MatchesActive ContractsParents PaymentsInterview Status- client conversion now happens in-place on
Parent Intake FormsusingClient Statusplus structured metadata appended toNoteTBC Doula DatabaseProvider Directoryamazon productsBlog PostsNewsletter SignupsAdmin Payments
- live approval workflow now also stores:
- structured approval metadata in
TBC Doula Database.Notes - mentor roster labels in
Assigned Mentor/Mentees - provider-directory publication state through
Provider Directory
- structured approval metadata in
Current Recommendation
Use the current code model in airtable.ts as the baseline for tomorrow.
Do not try to redesign the entire Airtable architecture in the same session unless you explicitly want to stop and do a schema migration pass first.
The fastest safe path from here is:
- Validate the two public write paths safely against live Airtable
- Add only the missing fields/tables needed for invoices and remaining finance ops
- Keep using the current multi-base model
- Update docs and tracker state as each workflow turns live
Safety Rule Before Any Live Write Test
Do not run a real production Airtable write just because API auth works.
Reason:
Parent Databasehas active create/update-triggered automations- those automations can send Gmail messages, post to Slack, append to Google Sheets, and trigger contract/availability workflows
That means a single test insert can create real side effects.
Allowed test modes, in order:
- sandbox/test base copy
- production base with relevant automations temporarily disabled
- production base with explicit operator approval for the side effects
Non-negotiables:
- no Airtable delete operations without explicit user approval
- no bulk test inserts
- no write tests against
Parent Intake Formswhile assuming they are “safe”
Environment Variables To Confirm
These are the Airtable environment variables the app currently expects:
AIRTABLE_API_KEY=
AIRTABLE_PARENTS_BASE_ID=
AIRTABLE_DOULAS_BASE_ID=
AIRTABLE_PRODUCTS_BASE_ID=
AIRTABLE_MARKETING_BASE_ID=
AIRTABLE_ADMIN_BASE_ID=
For the next implementation wave, the required ones are:
AIRTABLE_API_KEYAIRTABLE_PARENTS_BASE_IDAIRTABLE_DOULAS_BASE_IDAIRTABLE_MARKETING_BASE_IDAIRTABLE_ADMIN_BASE_ID
AIRTABLE_PRODUCTS_BASE_ID is still optional for intake/application/matching work.
Current Local-Only Flows To Replace
Parent intake form
- UI/form:
parent-intake-form.tsx - server write path:
route.ts - current behavior: posts through the API into Airtable, but live production verification is still handled carefully because create-triggered automations are active
Doula application form
- UI/form:
doula-application-form.tsx - server write path:
route.ts - current behavior: posts through the API into
TBC Doula Database, with live validation still handled carefully because webhook side effects are active
Doula availability responses
- API write path:
route.ts - client hook:
useDoulaMatchResponses.ts - current behavior: reads and writes
available/not_availableresponses againstParent-Doula Matches - requested-doula-unavailable branch:
/api/matchesnow sends the single client-facing email path server-side and stampsrequestedDoulaUnavailableEmailSentAtinto the match metadata so retries do not duplicate the notification - privacy boundary: doula email and phone should not be stored on
Parent-Doula Matches; match rows should only carry doula identity needed for workflow state, while private contact info stays onTBC Doula Database
Doula approval, directory publication, and mentorship
- approval write path:
route.ts - workflow layer:
doula-approval-workflow.ts - current behavior:
- promotes approved applicants in
TBC Doula DatabasetoOfficially Onboarded - stores canonical approval and mentorship metadata in
Notes - updates mentor roster labels in
Assigned Mentor/Mentees - creates, updates, or removes the linked
Provider Directoryrecord based on admin visibility choice - powers
/admin/doula-applications/[id],/admin/doulas,/admin/mentors, and/doula/mentor
- promotes approved applicants in
Interview scheduling
- shared Airtable path:
route.ts,route.ts,interviews.ts - booking write path:
doula-profile-page.tsx - current behavior: writes booked interviews into
Interview Statusthrough Airtable-backed/api/appointments
Doula scheduling availability
- availability write path:
route.ts - current behavior: persists
Interview Availability JSONandInterview Time Off JSONdirectly on the canonical doula record inTBC Doula Database
Recommended Airtable Scope For Tomorrow
Keep / confirm existing source tables
- Parents base:
Parent Intake FormsParent-Doula MatchesActive ContractsParents PaymentsInterview Status
- Doulas base:
TBC Doula DatabaseProvider Directory
- Marketing base:
Blog PostsNewsletter Signups
- Admin base:
Admin Payments
Add only the missing tables required by current app behavior
InvoicesDoula AvailabilityTime Off
Why The Current Matching Table Is Likely Enough
The current live Airtable base already has Parent-Doula Matches, which is materially better than the older generic schema assumptions.
What it already gives us:
- parent intake link
- doula identity fields
- match date
- match status
- source of match
- notes
- contract link
- interview link
What still needs to be verified or added for app parity:
- explicit doula availability response semantics
- requested-doula-unavailable tracking
- response timestamps
- visibility-to-client rules, if needed
Recommendation:
- do not create a new match table unless
Parent-Doula Matchesproves insufficient at the field level - prefer extending
Parent-Doula Matchesover introducing a duplicate domain table - current app implementation still stores structured app metadata in
Notesunder aTBC_MATCH_METAprefix, but the live table now also has first-class response fields for cleaner Airtable-side reporting and dedupe
Field Mapping: Parent Intake Form -> Parent Intake Forms
| Marketing form field | Current local key | Airtable field to target tomorrow | Notes |
|---|---|---|---|
| Birthing Person's First Name | firstName | First Name | already implied by current mapper |
| Birthing Person's Last Name | lastName | Last Name | already implied by current mapper |
email | Email | already implied by current mapper | |
| Phone | countryCode + phone | Phone | store as a normalized combined number |
| Estimated Due Date | estimatedDueDate | Estimated Due Date | already implied by current mapper |
| City | city | Address or City | current code uses Address; confirm which field the existing base actually uses |
| Delivery Hospital Name | deliveryHospitalName | Delivery Location | current code references Delivery Location with a trailing space; normalize this tomorrow if possible |
| Birth History | birthHistory | Birth History | new field likely needed |
| Type of support | supportType | Birth/Postpartum | current code already expects this field name |
| Specific doula interest | doulaInterest | Interested In Specific Doula(s) Or Would Like To Connect With Any Available Doula(s)? Please Specify * | current code already expects this long field name |
| Insurance coverage | insuranceCoverage | Covered By Insurance? | current code already expects this field name |
| Kaiser benefit flag | useKaiserBenefit | Kaiser Benefit? | current code already expects this field name |
| Out-of-pocket flexibility | outOfPocketFlexibility | Out Of Pocket Flexibility | new field likely needed |
| Specific budget | specificBudget | Specific budget? | current code expects Specific budget? with a trailing space; normalize if possible |
| Vision of support | visionOfSupport | What Is Your Vision For Birth/Birth Support | current code already expects this field name |
| How heard about TBC | howHeard | How Did You Hear About Us? | current code already expects this field name |
| Referral source detail | referralSource | Referral Source | new field likely needed |
| Submission timestamp | derived | Submission Date | can be created time or written explicitly |
| Needs consultation | derived | Needs Consultation | current local rule: true when specific doula interest is blank |
| Workflow status | derived/admin | Client Status | set by admin workflow or automation, not by public form |
Field Mapping: Doula Application -> TBC Doula Database
| Marketing form field | Current local key | Airtable field to target tomorrow | Notes |
|---|---|---|---|
| First Name | firstName | Doula First Name | already implied by current mapper |
| Last Name | lastName | Doula Last Name | already implied by current mapper |
email | Email | already implied by current mapper | |
| Areas served | areasServed | Areas Served | already implied by current mapper |
| Type of Doula Support | typeOfSupport | Type of Doula Support | already implied by current mapper |
| Years of experience | yearsOfExperience | Years of Experience | already implied by current mapper |
| Other services offered | otherServices | Other Services Offered | already implied by current mapper |
| How did you hear about us? | howHeard | How Did You Hear About Us? | likely needs to be added or confirmed |
| Formal training / certification | educationHistory | Formal Training / Certification | new field likely needed unless there is already an equivalent |
| Tell us more about yourself | aboutYourself | Background | current code already maps Background onto doula bio |
| Application status | derived | Application Status | should default to something like Submitted or New Application |
Important Doula Application Gap
Tomorrow should not blindly reuse the current generic createDoula() path without checking it first.
Why:
airtable.tscurrently writes only a partial doula profile shape- it does not currently write all of the new public application fields
Recommended fix:
- add a dedicated
createDoulaApplicationRecord()mapper, or - extend
doulaToAirtable()so it fully supports the public application payload
Option 1 is cleaner for tomorrow.
Recommended Current Interview Table: Interview Status
Use the live Interview Status table as the baseline. TBC calls these Interviews, even though the current app type is still Appointment.
| Field Name | Type | Notes |
|---|---|---|
| Parent-Doula Match | Link | already exists live |
| Interview Type | Single select | already exists live |
| Interview Date/Time | Date time | already exists live |
| Interview Status | Single select | already exists live |
| Parent Interview Feedback | Long text | already exists live |
| Doula Interview Feedback | Long text | already exists live |
| Interview Outcome | Single select | already exists live |
| Notes | Long text | already exists live |
| Next Steps (AI) | AI text | already exists live |
Likely additions still needed for app parity:
- Google event ID
- meeting link
- cancel reason
- confirmed at / completed at / cancelled at
Automation Ownership
Airtable should own
- parent intake confirmation / account-invite email
- doula application confirmation / account-invite email
- requested-doula-unavailable branch marker in
Parent-Doula Matches
App should own
- form validation
- writing records into Airtable
- reading records back into portal pages
- doula availability response actions
- current requested-doula-unavailable email send path until a dedicated Airtable automation replaces it
- client-side success/error states
- interview booking creation
Later integrations
- Google Calendar event creation
- Google Meet link insertion
- any webhook-based sync between Airtable and external systems
Confirmed automation inventory and risk
Parent Database active automations
Parent Sign Up CreatedPostpartum Check-In!First Birthday EmailFinal Payment ReminderEmail response to referral formParent - Hired to ContractNew Contracts to Bookkeeping SpreadsheetPost to AvailabilityClosed Contracts
Confirmed trigger detail:
Parent Sign Up Created- when a record is created in
Parent Intake Forms - sends email
- branches on
Kaiser Benefit?
- when a record is created in
Operational consequence:
- a real parent-intake write can trigger Gmail, Slack, Google Sheets, and downstream workflow actions
Doula Database active automations
Directory Doula Confirmation Email With Payment Link[TBC Doula Database] Send Webhook when Record is Updated[Doula Directory] Send Webhook when Record is Created[TBC Doula Database] Send Webhook when Record is Created copy
Inactive:
New Doula Sign Up Email Confirmation With Doula Profile FormUpdate Record via Form V2[Join The Team Form Submission] ...Yurii
Operational consequence:
- doula writes can trigger webhook side effects immediately
Family Favorites active automations
Send Webhook [Record Updated]Send Webhook [Record Created]
Marketing
No automation inventory confirmed yet.
Payments
- old
Paymentsbase is deleted - any screenshot of that base should be treated as stale
- current finance-op base is
TBC Admin Database Parent DatabasecontainsParents Payments- canonical model:
Active Contracts= canonical contract-economics record once PandaDoc metadata is ingestedParents Payments= canonical external money-in ledgerAdmin Payments= canonical internal contract-level finance and payout ledger
- relationship model:
- one active contract has many parent payment receipts
- one active contract has one admin finance ledger row
- business rules:
- PandaDoc creates and sends contracts to parents
- TBC collects 50% of the contract value upfront when the contract is signed
- 100% of the contract payment is collected by TBC
- TBC pays itself the referral fee from the full contract payment, then pays the doula
- birth-contract referral fees range from 10% to 20% depending on doula seniority and whether TBC handles Kaiser billing
- field ownership:
Active Contracts: total contract value, deposit due, balance due, referral fee percent, referral fee amount, doula payout obligation, Kaiser handling, PandaDoc referenceParents Payments: contract, payment stage, gross amount received, payment method, paid date, receipt status, external referenceAdmin Payments: contract, total received to date, remaining due, referral fee captured, doula payout due, payout status, payout method, bookkeeping notes
Recommended Tomorrow Implementation Order
- Run one controlled live validation for the parent intake write path
- Run one controlled live validation for the public doula application write path
- Decide whether
Admin Paymentsshould keep structuredNotesmetadata or gain first-class payout fields - Activate the existing PandaDoc send/status/webhook scaffold with live credentials and webhook registration
- Add Google Calendar / Meet sync once production interview persistence is stable
Safe test procedure
Before any live production-base write:
- confirm whether the relevant automations are enabled
- if enabled, choose one:
- disable them temporarily
- use a sandbox copy
- accept the side effects explicitly
- use one clearly labeled test record only
- do not run any delete/cleanup operation without explicit approval
Remaining Code Tasks
Parent intake
- complete one controlled live submit validation against production Airtable
- confirm downstream email and automation behavior
Doula application
- complete one controlled live submit validation against production Airtable
- confirm webhook side effects and downstream email behavior
Doula approval workflow
- confirm that the approved-doula metadata stored in
Notesis acceptable long-term or replace it with first-class Airtable fields - confirm that
Provider Directoryrows created from approved doulas match the intended public listing format - confirm mentor roster labels in
Assigned Mentor/Menteesare enough for ops visibility
Match responses
- monitor whether
Parent-Doula Matchescan fully stop depending on structuredNotesmetadata now that first-class response fields exist
Interviews
- verify that
Interview Statussupports the production interview workflow without additional schema changes
Payments and invoices
/api/invoicesand the doula invoice creation/detail routes are now Airtable-backed through theInvoicestable inTBC Admin DatabaseWORK-293is complete: signed webhook reconciliation now uses deterministic idempotency keys and creates contract-linked receipt records exactly once- decide whether
Admin Paymentsshould gain first-class payout fields instead of relying on structuredNotes
Remaining Questions
- Are the current Airtable automations already attached to:
Parent Intake FormsTBC Doula Databaseor do they use different source tables?
- Does the parent intake base already have fields for:
- birth history
- out-of-pocket flexibility
- referral source
- needs consultation
- Does the canonical doula destination already have fields for:
- how heard
- training/certification answer
- application status default
- What additional interview fields are needed beyond the current
Interview Statustable? - Should
Admin Paymentsstay metadata-driven inNotesor gain first-class payout fields? - Which PandaDoc template ids should map to Birth, Postpartum, and Extended contract packages in production?
Next Call Checklist
- Open the Parents base
- Open the Doulas base
- Open the TBC Admin base
- Review the existing automations together
- Confirm exact table names used by those automations
- Confirm exact field names used by those automations
- Confirm live create-trigger and webhook side effects before any production write validation
- Decide whether parent-intake live testing will use sandbox, disabled automations, or accepted side effects
- Test one real parent intake submission end to end only after the testing mode is approved
- Test one real doula application end to end
- Define the invoice table contract
- Wire
/api/invoicesand the invoice surfaces - Decide whether
Admin Paymentsneeds first-class payout fields - Re-test
/parent-intake-form,/doula-sign-up,/doula/leads,/client/matches,/client/search/d1,/client/appointments,/doula/calendar - Re-test
/client/payments,/admin/payments,/doula/invoices
Bottom Line
The Airtable cutover is now in place for intake, doula applications, matching, interviews, and payment ledgers.
The next phase is narrower:
- validate the two public write paths safely in production
- refine invoice approval and payout operations
- activate the PandaDoc scaffold with live credentials, webhook registration, and one controlled send test