> ## Documentation Index
> Fetch the complete documentation index at: https://docs-terra.withunify.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Tideswell/Jester/Zuiyo Parity Matrix

> Feature-by-feature comparison between the current stack and Terra, with gap analysis and validation checklist

# 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 Type                     | Tideswell                                                | Jester Stores As           | Terra                           | Status        | Notes                                                                                        |
| ------------------------------ | -------------------------------------------------------- | -------------------------- | ------------------------------- | ------------- | -------------------------------------------------------------------------------------------- |
| Single line text               | `SingleLineQuestion`                                     | TEXT                       | Text field                      | ✅ Parity      |                                                                                              |
| Multi-line text                | `SingleLineQuestion` (multiLine flag)                    | TEXT                       | Text field (multiline variant)  | ✅ Parity      |                                                                                              |
| Radio / checkbox               | `ChoiceQuestion`                                         | TEXT\[] array              | Choice field                    | ✅ Parity      |                                                                                              |
| Dropdown                       | `ChoiceQuestion` (displayFormat: dropdown)               | TEXT\[] array              | Choice field (dropdown variant) | ✅ Parity      |                                                                                              |
| Date                           | `DateQuestion`                                           | DATE                       | Date field                      | ✅ Parity      | Both support min/max date constraints                                                        |
| Number                         | `NumericalQuestion`                                      | NUMERIC                    | Number field                    | ✅ Parity      | Both support integer, whole, currency, decimal                                               |
| Address                        | `AddressQuestion`                                        | 5+ TEXT columns            | Address field                   | ✅ Parity      | Both use Smarty for validation                                                               |
| File upload                    | `FilesQuestion`                                          | file\_id, orig\_name, url  | Files field                     | ✅ Parity      | Tideswell: Google Drive only. Terra: Supabase Storage + Google Drive                         |
| ID verification                | `IdVerificationQuestion`                                 | 60+ Plaid columns          | Plaid IDV field                 | ✅ Parity      |                                                                                              |
| Bank verification              | `BankVerificationQuestion`                               | account\_id, routing, mask | Plaid Bank field                | ✅ Parity      |                                                                                              |
| Info / display block           | `InfoQuestion`                                           | Not stored                 | Info block                      | ✅ Parity      | Terra adds markdown + alert variants                                                         |
| Grouped section                | `GroupedQuestion` (nested container)                     | N/A                        | ⚠️ Verify                       | 🔲 Validate   | Tideswell supports nested question groups — confirm Terra handles same nesting depth         |
| Repeated / referenced question | `RepeatedQuestion` (references another question by name) | N/A                        | ❌ Not found                     | 🔴 Gap        | Tideswell can reference an existing question elsewhere in the form. Terra equivalent unclear |
| Signature                      | Not in Tideswell                                         | N/A                        | Signature field                 | ➕ Terra extra |                                                                                              |
| Payment                        | Not in Tideswell                                         | N/A                        | Payment field                   | ➕ Terra extra |                                                                                              |

***

## Conditional Logic

| Capability                         | Tideswell               | Terra                                  | Status        | Notes                                                              |
| ---------------------------------- | ----------------------- | -------------------------------------- | ------------- | ------------------------------------------------------------------ |
| AND groups                         | ✅                       | ✅                                      | ✅ Parity      |                                                                    |
| OR groups                          | ✅                       | ✅                                      | ✅ Parity      |                                                                    |
| Greater than (numeric)             | `FLOAT_GT`              | `gt`, `gte`                            | ✅ Parity      |                                                                    |
| Less than (numeric)                | `FLOAT_LT`              | `lt`, `lte`                            | ✅ Parity      |                                                                    |
| Equals / not equals                | Implied                 | `eq`, `neq`                            | ✅ Terra more  | Terra explicit                                                     |
| Array intersection (multi-select)  | `INTERSECTS_WITH`       | `in`                                   | ✅ Parity      |                                                                    |
| Text contains / starts / ends      | ❌                       | `contains`, `starts_with`, `ends_with` | ➕ Terra extra |                                                                    |
| Age-based rules                    | ❌                       | `minAge`, `maxAge`                     | ➕ Terra extra |                                                                    |
| Field exists check                 | ❌                       | `exists`                               | ➕ Terra extra |                                                                    |
| Recursive nesting                  | ✅                       | ✅                                      | ✅ Parity      |                                                                    |
| Reference another question's value | ✅ (`answerRaw` by name) | ✅                                      | ✅ Parity      |                                                                    |
| Legacy logicInRules (2D array)     | ✅ (older forms)         | ❌                                      | 🔴 Gap        | Some older forms may use this. Check which active forms rely on it |

***

## Submission Storage & Data Integrity

| Capability                                      | Tideswell/Jester                              | Terra     | Status         | Notes                                                                                                        |
| ----------------------------------------------- | --------------------------------------------- | --------- | -------------- | ------------------------------------------------------------------------------------------------------------ |
| 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 | 🔲 Validate    | Tideswell 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 | 🔲 Validate    | Confirm Terra handles re-submissions of same ID correctly                                                    |
| Silent failure prevention                       | ⚠️ Jester can fail silently on webhook errors | ✅ Better  | ✅ Terra better | Terra 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.

| Capability                          | Zuiyo (current)                                                                                                                                        | Terra                                   | Status                        | Notes                                                                                                                               |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Postgres → Airtable field mapping   | ✅ Via struct tags or field name matching                                                                                                               | ✅ Native integration                    | ✅ Parity                      | Mechanism differs; outcome same                                                                                                     |
| Supported Airtable field types      | singleLineText, email, url, multilineText, phoneNumber, number, currency, singleSelect, multipleSelects, date, dateTime, checkbox, multipleAttachments | ✅ Most types                            | 🔲 Validate                   | Confirm Terra maps all Zuiyo-supported types                                                                                        |
| Batch inserts (Airtable API limit)  | ✅ 10 records/batch                                                                                                                                     | ✅                                       | 🔲 Validate                   | Confirm Terra respects Airtable rate limits                                                                                         |
| Retry on Airtable API failure       | ✅ 3 retries                                                                                                                                            | ⚠️ Verify                               | 🔲 Validate                   | Confirm 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 | 🔲 Validate                   | Confirm 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 verify** | This 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

| Capability                    | Tideswell                             | Terra         | Status              | Notes                                                                                                     |
| ----------------------------- | ------------------------------------- | ------------- | ------------------- | --------------------------------------------------------------------------------------------------------- |
| Applicant authentication      | Firebase Identity Platform            | WorkOS        | 🔲 Validate         | Different 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     | 🔲 Validate         | Some programs allow no-account submissions                                                                |
| Existing Tideswell accounts   | Firebase UIDs                         | N/A           | 🔴 Migration needed | Applicants with existing Tideswell accounts need migration path to WorkOS if they need to log in to Terra |

***

## File Uploads

| Capability                       | Tideswell                      | Terra        | Status        | Notes |
| -------------------------------- | ------------------------------ | ------------ | ------------- | ----- |
| Google Drive storage             | ✅ Primary storage              | ✅ Supported  | ✅ Parity      |       |
| Supabase Storage                 | ❌                              | ✅            | ➕ Terra extra |       |
| Per-question drive folder config | ✅ `driveFolderId` per question | ✅            | ✅ Parity      |       |
| File size limit                  | 16 MB                          | Configurable | ✅ Parity      |       |
| MIME type restrictions           | ✅ `accept` field               | ✅            | ✅ Parity      |       |
| File count limits                | ❌                              | ✅            | ➕ Terra extra |       |

***

## Notifications

| Capability                          | Tideswell                    | Terra    | Status        | Notes                                                         |
| ----------------------------------- | ---------------------------- | -------- | ------------- | ------------------------------------------------------------- |
| 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 | ✅        | 🔲 Validate   | Confirm Terra's retry behavior matches or exceeds Tideswell's |
| Webhook event history               | ✅                            | ✅        | ✅ Parity      |                                                               |

***

## Admin Interface

| Capability                                  | Tideswell                                  | Terra     | Status      | Notes                                                                                            |
| ------------------------------------------- | ------------------------------------------ | --------- | ----------- | ------------------------------------------------------------------------------------------------ |
| 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 | 🔲 Validate | Check if Terra has CSV import for submissions                                                    |
| CSV export                                  | ✅                                          | ✅         | ✅ Parity    |                                                                                                  |
| i18n string customization per form          | ✅                                          | ✅         | ✅ Parity    |                                                                                                  |
| Groups / team submissions                   | ✅ Multiple accounts per group              | ⚠️ Verify | 🔲 Validate | Tideswell 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

| Capability                  | Tideswell                         | Terra | Status        | Notes                                     |
| --------------------------- | --------------------------------- | ----- | ------------- | ----------------------------------------- |
| 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)              | ❌     | 🔴 Gap        | Check 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:

| # | Gap                                    | Severity    | Owner         | Action                                                                                                             |
| - | -------------------------------------- | ----------- | ------------- | ------------------------------------------------------------------------------------------------------------------ |
| 1 | **Outcome sync: Airtable → Terra**     | 🔴 Critical | David         | Verify or build — reviewers approve in Airtable, applicants must see status in Terra                               |
| 2 | **GroupedQuestion nesting**            | 🟡 High     | David + May   | Test: does Terra support the same nesting depth as Tideswell's GroupedQuestion?                                    |
| 3 | **RepeatedQuestion**                   | 🟡 High     | David         | Does Terra have a way to reference/reuse a question from elsewhere in the form? If not, check which forms use this |
| 4 | **Legacy logicInRules**                | 🟡 High     | Brian + May   | Identify which active forms use the legacy 2D rule format — can they be rewritten as standard conditions?          |
| 5 | **Anonymous / guest submissions**      | 🟡 High     | David         | Confirm Terra supports unauthenticated submissions for programs that don't require applicant accounts              |
| 6 | **Airtable sync retry reliability**    | 🟡 High     | David         | Confirm Terra retries failed Airtable syncs and that no submissions can silently fail to sync                      |
| 7 | **Outcome field exposed to applicant** | 🟡 High     | David + May   | Confirm the admin-set outcome (e.g., "Approved: \$3,000") is visible to the applicant in Terra                     |
| 8 | **Airtable mapping config**            | 🟡 High     | Brian + David | Decide: 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
