Internal

System Docs

How the approval workflow works, end to end.


Workflow Overview

1
User submits form

Netlify Forms stores the submission. submission-created saves to Supabase and sends all notification emails via Resend (GYE admin with approve/deny buttons if subsidy, or Gentech + GYE FYI if no subsidy).

2
Admin clicks approve/deny

admin-action validates the secret, updates Supabase, and sends user & Gentech emails via Resend.

3
User responds (if denied/partial)

User clicks “still interested” → admin-action updates Supabase and emails Gentech via Resend.

4
Accountability partner setup

If user opted for uninstall protection: partner email can be provided on the form, or the user receives a link to partner-setup to add it later. If the partner email was already verified on another submission, it’s auto-approved. Otherwise the partner receives an invitation email and must click “I Agree.”

5
Partner reminders

When a tech marks a filter as installed and no partner is set, the user gets a reminder email. For sponsored users, partner-reminder-cron runs daily and sends a warning at 30 days post-install, notifying both the user and admin.


Admin Actions

ActionWhoSecretResult
approve100AdminADMIN_SECRETApproved — 100% subsidy
approve50AdminADMIN_SECRETApproved — 50% subsidy
denyAdminADMIN_SECRETDenied — user asked if still interested
interestedUserUSER_ACTION_SECRETUser confirms interest after denial/partial
partner-approvePartnerUSER_ACTION_SECRETPartner agrees to be accountability partner
partner-approve-pausePartnerUSER_ACTION_SECRETPartner approves 24h pause (72h window)
partner-approve-removalPartnerUSER_ACTION_SECRETPartner approves full removal (72h window)

Action URL Format

/.netlify/functions/admin-action?id={id}&action={action}&email={email}&name={name}&secret={secret}&requested={50|100}


Environment Variables

VariablePurpose
ADMIN_SECRETAuthenticates admin action links
USER_ACTION_SECRETAuthenticates user “still interested” links
RESEND_API_KEYResend API key for sending emails
SUPABASE_URLSupabase project URL
SUPABASE_SERVICE_ROLE_KEYSupabase service role key (server-side access)
Gentech emails are hardcoded in lib/emails.mjs: TO support@gentechsolution.com, CC jperl@gentechsolution.com
GYE_ADMIN_EMAILGYE admin email for approval notifications (eyes.guard@gmail.com)

Netlify Functions

FunctionTriggerWhat it does
submission-createdNetlify form submissionSaves to Supabase, sends notification emails, sends partner invitation or setup link
admin-actionAdmin/user/partner clicks action linkUpdates Supabase, sends user & Gentech emails via Resend
admin-apiAdmin dashboard API callsCRUD operations, tech updates, partner email management, sends partner reminders on install
partner-setupUser visits /partner-setup?token=...Validates HMAC token, lets user enter partner email, sends invitation (or auto-approves if verified)
partner-reminder-cronDaily schedule (9 AM ET)Warns sponsored users & admin if no partner 30+ days post-install
admin-docsManualThis docs page
admin-emailsManualEmail templates reference page

Services

ServiceRole
NetlifyHosting, form submissions, serverless functions
SupabaseDatabase — stores all submissions, updated on every action
ResendTransactional email — sends from hello@kedusha.com
ZapierNo longer used — fully replaced by Supabase + Resend
Google SheetsNo longer used — replaced by Supabase
GitHubSource code (webshadoworg/sponsoredfilter), auto-deploys to Netlify

Supabase

Project: kiwhkqfepwzacskpvagk

Table: submissions

ColumnTypeDescription
idUUIDPrimary key (auto-generated)
netlify_idtextNetlify form submission ID (used in action URLs)
nametextUser’s name
emailtextUser’s email
phonetextPhone number
citytextCity
device_countintegerNumber of devices
devicestextDevice types
guidelinesbooleanAgreed to kedusha.com guidelines
sponsoredbooleanRequested financial assistance
discount_levelinteger50 or 100 (subsidy level requested)
subsidy_reasontextReason for subsidy
financial_commentstextAdditional financial info
commentstextGeneral comments
uninstall_protectionbooleanAccountability partner required for changes
partner_emailtextAccountability partner’s email
partner_statustextnull → approved (set when partner clicks “I Agree” or auto-approved if previously verified)
statustextpending → ready / waiting-user / waiting-partner
decisiontextapprove100 / approve50 / deny
user_responsetextinterested (after deny/partial)
vip_servicebooleanVIP in-person setup requested
kedusha_account_idintegerAuto-increment account ID (displayed as KED-XXXX)
gentech_usernametextGentech platform username
tech_statustextcontacted / scheduled / installed / uninstalled / unresponsive / not-interested
tech_notestextTechnician notes
tech_licensesintegerNumber of license installations
tech_updated_attimestamptzLast tech status update
email_bouncedbooleanEmail delivery failed
created_attimestamptzSubmission time
updated_attimestamptzLast update time

Additional Tables

submission_events — activity log (events like tech:installed, partner:invited, partner:auto-approved, partner:30day-warning)

devices — individual devices per submission (type, name, active status, gentech username)

protection_requests — pause/removal requests that require partner approval (72h window)

Supabase Status Lifecycle

Eventstatusdecisionuser_response
Form submit (no subsidy, no protection)ready
Form submit (no subsidy, with protection)waiting-partner
Form submit (subsidy)pending
Admin: approve100ready *approve100
Admin: approve50 (req 50)ready *approve50
Admin: approve50 (req 100)waiting-userapprove50
Admin: denywaiting-userdeny
User: interestedready *interested
Partner: approveready

— = no change (keep existing value)
* = becomes waiting-partner instead of ready if uninstall protection is enabled


Form Fields

FieldTypeDescription
nametextUser’s name
emailemailUser’s email
phonetelPhone number
citytextCity
device-countnumberNumber of devices
devicescheckboxesDevice types owned
daas-torahcheckboxAgrees to kedusha.com community guidelines
sponsoredcheckboxNeeds financial assistance
discount-levelradio50 or 100 (subsidy level requested)
subsidy-reasonradioReason for subsidy request
financial-commentstextareaAdditional financial context
commentstextareaGeneral comments
uninstall-protectioncheckboxWants accountability partner for changes
partner-emailemailAccountability partner’s email (optional, validated for format and not same as user email)
vip-servicehiddenVIP in-person setup (set by VIP page)