Functional Logic
The security review proves the system can’t be exploited. This section proves it works correctly.
Form Submission Flow
The most important code path. Everything flows throughsubmitFormResponse():
Steps 1–8 are synchronous — the submission must save before the user gets a
response. Step 9 (hooks) is non-blocking. If Airtable is down or a webhook
fails, the submission is already safe in the database.
src/app/actions.ts, submitFormResponse() (~line 2512)
Tests: 3 cases in form-renderer.test.tsx (rendering), integration coverage across encryption, rate limiting, and queue tests.
- Submit to a closed/unpublished form — should return a clear error, not a 500
- Submit 31 times in a minute — rate limiting should kick in
- Disable a webhook endpoint, submit a form — submission should still save
Notifications
Email (Resend) and SMS (Twilio) notifications fire on form events. Admin-only test sends verify provider configuration.What the tests prove
What the tests prove
- Event retrieval with filtering by form, channel, status - Pagination returns distinct results - Stats math: sent count = (sent + delivered), excludes failed/pending - Error categorization: invalid address, bounced, carrier rejected, rate limited, provider error - Admin-only enforcement on test email/SMS - Missing provider config caught (RESEND_API_KEY, Twilio credentials) - Per-form notification settings: auth enforced, insert vs update path, null handling
Async Queue
Post-submission hooks use an async queue with exponential backoff:null instead of throwing:
src/lib/__tests__/async-queue.test.ts
What the tests prove
What the tests prove
- Correct RPC payload structure for enqueue - Webhook gets 5 retries, others
get 3 - Queue errors return null (no crash) - Database timeout and connection
reset handled gracefully - Complex nested payloads preserved (unicode, special
chars, nested objects) - Backoff formula verified:
2^(n-1) * 30s
Airtable Sync
Bidirectional sync with loop prevention. System fields use_ prefix convention:
create, update, and upsert — no delete operation.
Tests: 15 cases in airtable-status-sync.test.ts
What the tests prove
What the tests prove
- Missing/disabled connections skip gracefully - Unmapped status fields skip
(no crash) - Only valid statuses accepted (submitted, pending, processing,
approved, rejected, withdrawn) -
_submission_idmapping required to find Airtable record - No delete operation exposed — records preserved on withdrawal - Sync loop prevention:airtable_syncsource blocks reverse trigger - Change source tracked for audit
Import Security
Forms can be imported from PDFs, images, and HTML. The import pipeline prevents user impersonation:import-security.test.ts
What the tests prove
What the tests prove
- Job ID contains authenticated user’s ID, not attacker’s - Unauthenticated
users rejected -
userIdparameter in request body ignored - Separate jobs for different users (no cross-contamination) - Max 8 images, max 10MB PDF, only PDF file type accepted