Skip to main content

Tideswell / Jester / Zuiyo → Terra Parity Matrix

How the Current Stack Works

Before comparing, it helps to understand that “Tideswell” is actually three systems working together:
Applicant fills form → Tideswell (form builder, Firebase auth, MongoDB)
                            ↓ webhook on submit
                        Jester (ingestion middleware, normalizes data → PostgreSQL)
                            ↓ cron sync (Zuiyo)
                        Airtable (reviewer works here, marks outcomes)
                            ↓ outcome sync back (Zuiyo)
                        Tideswell (outcome visible to applicant)
Terra replaces Tideswell and Jester natively. The Airtable sync is built into Terra directly. The open question is the outcome sync back — Zuiyo currently writes approval/denial outcomes back to Tideswell so applicants can see them. Terra needs equivalent behavior.

Form Field Types

Field TypeTideswellJester Stores AsTerraStatusNotes
Single line textSingleLineQuestionTEXTText field✅ Parity
Multi-line textSingleLineQuestion (multiLine flag)TEXTText field (multiline variant)✅ Parity
Radio / checkboxChoiceQuestionTEXT[] arrayChoice field✅ Parity
DropdownChoiceQuestion (displayFormat: dropdown)TEXT[] arrayChoice field (dropdown variant)✅ Parity
DateDateQuestionDATEDate field✅ ParityBoth support min/max date constraints
NumberNumericalQuestionNUMERICNumber field✅ ParityBoth support integer, whole, currency, decimal
AddressAddressQuestion5+ TEXT columnsAddress field✅ ParityBoth use Smarty for validation
File uploadFilesQuestionfile_id, orig_name, urlFiles field✅ ParityTideswell: Google Drive only. Terra: Supabase Storage + Google Drive
ID verificationIdVerificationQuestion60+ Plaid columnsPlaid IDV field✅ Parity
Bank verificationBankVerificationQuestionaccount_id, routing, maskPlaid Bank field✅ Parity
Info / display blockInfoQuestionNot storedInfo block✅ ParityTerra adds markdown + alert variants
Grouped sectionGroupedQuestion (nested container)N/A⚠️ Verify🔲 ValidateTideswell supports nested question groups — confirm Terra handles same nesting depth
Repeated / referenced questionRepeatedQuestion (references another question by name)N/A❌ Not found🔴 GapTideswell can reference an existing question elsewhere in the form. Terra equivalent unclear
SignatureNot in TideswellN/ASignature field➕ Terra extra
PaymentNot in TideswellN/APayment field➕ Terra extra

Conditional Logic

CapabilityTideswellTerraStatusNotes
AND groups✅ Parity
OR groups✅ Parity
Greater than (numeric)FLOAT_GTgt, gte✅ Parity
Less than (numeric)FLOAT_LTlt, lte✅ Parity
Equals / not equalsImpliedeq, neq✅ Terra moreTerra explicit
Array intersection (multi-select)INTERSECTS_WITHin✅ Parity
Text contains / starts / endscontains, starts_with, ends_with➕ Terra extra
Age-based rulesminAge, maxAge➕ Terra extra
Field exists checkexists➕ Terra extra
Recursive nesting✅ Parity
Reference another question’s value✅ (answerRaw by name)✅ Parity
Legacy logicInRules (2D array)✅ (older forms)🔴 GapSome older forms may use this. Check which active forms rely on it

Submission Storage & Data Integrity

CapabilityTideswell/JesterTerraStatusNotes
Submission ID<formId><8chars>✅ Parity
Status tracking✅ incomplete / submitted / withdrawn✅ Parity
Timestamp tracking✅ createdAt, submittedAt✅ Parity
IP geolocation on submit✅ address, country, city, lat, lon✅ Parity
Language on submit✅ Parity
Outcome field (admin-set, visible to applicant)⚠️ Verify🔲 ValidateTideswell has a dedicated outcome field admins set per submission. Verify Terra exposes this to applicants
Submission freezing after submit✅ Parity
Answer match / double-entry verification✅ (isAnswerMatchRequired)✅ Parity
Upsert on re-submission (same ID)✅ Jester uses ON CONFLICT DO UPDATE⚠️ Verify🔲 ValidateConfirm Terra handles re-submissions of same ID correctly
Silent failure prevention⚠️ Jester can fail silently on webhook errors✅ Better✅ Terra betterTerra has queue with retry. Verify retry logic on Airtable sync

Airtable Sync (The Critical Path)

This is the most important section. The Zuiyo→Airtable sync is the handoff to reviewers. If this breaks, reviewers don’t see applications.
CapabilityZuiyo (current)TerraStatusNotes
Postgres → Airtable field mapping✅ Via struct tags or field name matching✅ Native integration✅ ParityMechanism differs; outcome same
Supported Airtable field typessingleLineText, email, url, multilineText, phoneNumber, number, currency, singleSelect, multipleSelects, date, dateTime, checkbox, multipleAttachments✅ Most types🔲 ValidateConfirm Terra maps all Zuiyo-supported types
Batch inserts (Airtable API limit)✅ 10 records/batch🔲 ValidateConfirm Terra respects Airtable rate limits
Retry on Airtable API failure✅ 3 retries⚠️ Verify🔲 ValidateConfirm Terra retries failed syncs
Rate limiting✅ 8 concurrent max⚠️ Verify🔲 Validate
Mapping admin UI✅ Zuiyo has UI for managing column→field mappings✅ Terra has Airtable integration config🔲 ValidateConfirm Terra’s mapping config is as flexible as Zuiyo’s
Incremental sync (only new records)✅ By submitted_at timestamp⚠️ Verify🔲 Validate
Refresh existing records on update✅ ~10% refresh each sync to catch updates⚠️ Verify🔲 Validate
Outcome sync: Airtable → Terra✅ Zuiyo reads outcome field from Airtable, writes back to Tideswell via GraphQL⚠️ Unclear🔴 Critical gap to verifyThis closes the loop — reviewer approves in Airtable, applicant sees status in Terra. Does Terra receive status back from Airtable?
Sync history / logs✅ Zuiyo UI shows last 5 syncs with detailed logs✅ Terra has webhook event history✅ Parity
Manual sync trigger✅ Via Zuiyo API⚠️ Verify🔲 Validate
Decision required before validation: The Airtable field mapping currently lives in Zuiyo’s database (jester_airtable_mappings table). For Terra, this mapping can either:
  • Be configured identically to replicate current Zuiyo behavior (1:1 parity)
  • Be redesigned to take advantage of Terra’s richer data model
This needs Brian and David to align — it affects how validation is done.

Authentication

CapabilityTideswellTerraStatusNotes
Applicant authenticationFirebase Identity PlatformWorkOS🔲 ValidateDifferent providers. Behavior should be equivalent but existing Firebase accounts don’t auto-migrate
Tenant support✅ Firebase tenant isolation✅ WorkOS orgs✅ Parity
SSO / enterprise OAuth✅ Firebase✅ WorkOS✅ Parity
MFA✅ Group-level MFA required flag✅ WorkOS✅ Parity
API key auth for automation<uuid>:<form_id> format✅ Parity
Anonymous / guest submissions✅ Groups allow unauthenticated submit⚠️ Verify🔲 ValidateSome programs allow no-account submissions
Existing Tideswell accountsFirebase UIDsN/A🔴 Migration neededApplicants with existing Tideswell accounts need migration path to WorkOS if they need to log in to Terra

File Uploads

CapabilityTideswellTerraStatusNotes
Google Drive storage✅ Primary storage✅ Supported✅ Parity
Supabase Storage➕ Terra extra
Per-question drive folder configdriveFolderId per question✅ Parity
File size limit16 MBConfigurable✅ Parity
MIME type restrictionsaccept field✅ Parity
File count limits➕ Terra extra

Notifications

CapabilityTideswellTerraStatusNotes
Email on submission❌ (webhook-based only)✅ Resend➕ Terra extra
SMS✅ Twilio➕ Terra extra
Plain text email✅ SendGrid✅ Parity
HTML/template email➕ Terra extra
Webhook on submit✅ (primary mechanism)✅ Parity
Webhook retry (exponential backoff)✅ 12 attempts, ~24hr window🔲 ValidateConfirm Terra’s retry behavior matches or exceeds Tideswell’s
Webhook event history✅ Parity

Admin Interface

CapabilityTideswellTerraStatusNotes
Form builder✅ Parity
Drag-drop reorder✅ Parity
Submission list view✅ Parity
Filter submissions by status✅ Parity
Update submission status✅ Parity
Update outcome field (admin-set)⚠️ Verify🔲 Validate
CSV bulk import✅ With header-to-question mapping⚠️ Verify🔲 ValidateCheck if Terra has CSV import for submissions
CSV export✅ Parity
i18n string customization per form✅ Parity
Groups / team submissions✅ Multiple accounts per group⚠️ Verify🔲 ValidateTideswell supports group-scoped submissions where multiple accounts can view the same submission
Featured questions (submission preview)✅ Select which questions show in list view⚠️ Verify🔲 Validate
Form scheduling (auto-publish / auto-close)✅ Parity
Post-submit redirect URL✅ Parity

Validation

CapabilityTideswellTerraStatusNotes
Required / optional✅ Parity
Min / max length✅ Parity
Numeric type validation✅ integer, whole, currency, float✅ Parity
Date min / max✅ Parity
Address validation (Smarty)✅ Parity
Answer match (double-entry)isAnswerMatchRequired✅ Parity
Age-based validation➕ Terra extra
Legacy logicInRules✅ (some older forms)🔴 GapCheck which active forms use this pattern

Summary: Gaps That Block v1

These must be resolved before Terra can replace Tideswell/Jester/Zuiyo for any live program:
#GapSeverityOwnerAction
1Outcome sync: Airtable → Terra🔴 CriticalDavidVerify or build — reviewers approve in Airtable, applicants must see status in Terra
2GroupedQuestion nesting🟡 HighDavid + MayTest: does Terra support the same nesting depth as Tideswell’s GroupedQuestion?
3RepeatedQuestion🟡 HighDavidDoes Terra have a way to reference/reuse a question from elsewhere in the form? If not, check which forms use this
4Legacy logicInRules🟡 HighBrian + MayIdentify which active forms use the legacy 2D rule format — can they be rewritten as standard conditions?
5Anonymous / guest submissions🟡 HighDavidConfirm Terra supports unauthenticated submissions for programs that don’t require applicant accounts
6Airtable sync retry reliability🟡 HighDavidConfirm Terra retries failed Airtable syncs and that no submissions can silently fail to sync
7Outcome field exposed to applicant🟡 HighDavid + MayConfirm the admin-set outcome (e.g., “Approved: $3,000”) is visible to the applicant in Terra
8Airtable mapping config🟡 HighBrian + DavidDecide: replicate Zuiyo mapping 1:1, or redesign? This decision gates the validation checklist

Validation Checklist (to be completed by Brian + May)

Once the gaps above are resolved, this is the sign-off list for Terra v1 production.

Form Building

  • All field types used in current active programs exist in Terra
  • Conditional logic on at least one complex form produces same show/hide behavior as Tideswell
  • Multi-language form renders correctly in at least 2 languages
  • Form scheduling (auto-publish, auto-close) works as expected

Submission Integrity

  • Test submission on a real form: data lands in Terra database completely and accurately
  • File upload attaches correctly to submission
  • Failed submission does not silently disappear — produces visible error
  • Re-submission of same ID behaves correctly (upsert, not duplicate)

Airtable Sync

  • Sync a test submission: correct fields appear in correct Airtable columns
  • Sync failure is logged and retried — data does not silently fail to reach Airtable
  • Outcome sync: reviewer marks outcome in Airtable → applicant sees updated status in Terra

Security

  • Submission is not accessible without proper authorization
  • PII does not appear in error logs or Sentry
  • File uploads are not publicly accessible URLs

Admin

  • Submission list shows correct data for a test program
  • Status can be updated on a submission
  • Outcome field can be set by admin and is visible to applicant
Sign-off: Brian _______ May _______ Date _______

What Terra Has That Tideswell Does Not

These are capabilities Terra ships with that can be unlocked after v1 is stable:
  • Field block library (reusable groups of fields across forms)
  • Per-field encryption for PII
  • Audit logging on all data changes
  • SMS notifications (Twilio)
  • Rich email templates (Resend)
  • Program hierarchy (workspace → program → form)
  • Form versioning and immutable submission records
  • Age-based conditional logic operators
  • Advanced file handling (count limits, size limits, Supabase Storage)
  • Signature field
  • Markdown info blocks with alert variants