Onboard.
Storage & Integration
Integration Guide · v1.0

From prototype to production.

The current portal stores files as session metadata — enough for a demo. To deploy this for real staff with actual sensitive documents (I-9s, IDs, bank info), you need proper backend storage, encryption, and access controls. Here's the shortest path there.

On this page

  1. The architecture, at a glance
  2. Storage options & what to pick
  3. The upload flow, step by step
  4. API endpoints you'll need
  5. Security & compliance essentials
  6. Wiring it to Zapier & Twilio
  7. Launch checklist
Chapter 01

The architecture, at a glance.

You need four things talking to each other: the portal (what the staff member sees), an API (to authenticate and coordinate), object storage (where the actual files live), and a database (to track status, ownership, and metadata). The portal never touches the storage bucket directly — it asks the API for a time-limited upload link, and the file goes straight from the user's browser to the bucket.

1
Portal
Browser
2
API
Auth + coord.
3
Signed URL
Time-limited
4
Storage
Encrypted
5
Database
Metadata
Why this pattern

Files never pass through your API server, which keeps it cheap and fast. Your API only hands out short-lived signed URLs (typically 5–15 minutes) that grant temporary write access to a specific path in the bucket. Standard pattern for Dropbox, Google Drive, and most file-upload SaaS.

Chapter 02

Storage options, matched to your stack.

Since you're already on Google Workspace with Zapier in the mix, you have a few natural choices. Here's how they compare:

AWS S3

Full control
  • Industry standard for this exact use case
  • Bucket policies + KMS encryption
  • Lifecycle rules (auto-archive old hires)
  • Requires AWS account & IAM setup
  • Zapier integration available
~$0.023/GB/month

Supabase Storage

If you want a full backend
  • Storage + Postgres + Auth in one
  • Row-level security for access control
  • Signed URLs built in
  • Fastest path if starting from scratch
  • Generous free tier
Free → $25/mo

If you already live in Google Workspace, start with Drive. It's the lowest-friction option and your team already has access controls figured out. Move to S3 or Supabase only if you outgrow Drive's API limits or need per-file audit trails.

Chapter 03

The upload flow, step by step.

Here's what happens when a staff member clicks "Upload" on their W-4:

1. Request a signed URL

The portal sends the doc type and filename to your API. The API verifies the hire's session, generates a unique storage path, and returns a time-limited signed upload URL.

// Portal → API
POST /api/uploads/request
{
  "hire_id": "h_8f3k2",
  "doc_type": "w4",
  "filename": "w4-2026.pdf",
  "mime": "application/pdf",
  "size": 284511
}

// API → Portal
{
  "upload_url": "https://storage.../signed?token=...",
  "storage_key": "hires/h_8f3k2/w4/2026-04-14-w4.pdf",
  "expires_at": "2026-04-14T15:32:00Z",
  "upload_id": "up_a9b2c"
}

2. Upload directly to storage

The browser PUTs the file straight to the signed URL. This is the heavy part of the transfer, and it never touches your server.

3. Confirm the upload

Once done, the portal tells the API the upload finished. The API verifies the file exists at the expected path, runs a virus scan if you have one wired up, and writes the metadata row to the database.

// Portal → API
POST /api/uploads/confirm
{
  "upload_id": "up_a9b2c",
  "checksum": "sha256:4f2a..."
}

// API writes to DB
INSERT INTO documents (
  id, hire_id, doc_type, storage_key,
  original_filename, mime, size, uploaded_at, status
) VALUES (...);

4. Fire the nudge-system event

After a successful upload, your API publishes an event like document.uploaded. That's what the nudge rules (previous page) subscribe to — closing the loop between upload activity and downstream notifications.

Chapter 04

API endpoints you'll need.

Minimum viable set. You can build these in anything — Next.js API routes, Node/Express, Python/FastAPI, or even a no-code layer like Xano if you're moving fast.

Shortcut

Supabase gives you 80% of this for free via auto-generated REST APIs on top of your Postgres schema. You'd only need to write the signed-URL endpoint and the event publisher.

Chapter 05

Security & compliance essentials.

You're handling I-9s, government IDs, and bank details. This isn't a blog comment form. These are the non-negotiables:

Encryption

Encryption at rest (server-side encryption on the bucket) and in transit (TLS only). All three storage options above handle this by default. Don't disable it.

Access control

Staff can only access their own documents. Admins can access all. Nobody on the engineering side should have read access to the bucket by default — grant it temporarily when debugging, revoke when done.

Retention policy

I-9s must be retained for 3 years after hire date or 1 year after termination, whichever is later. W-4s for 4 years. Build a lifecycle rule that archives to cold storage at those boundaries rather than deleting.

Audit log

Every document access — views, downloads, deletes — gets logged with who, what, when. This saves you during any employment dispute or audit.

Virus scanning

Staff upload from personal devices. ClamAV in a Lambda trigger (for S3) or a Drive API scan hook is cheap insurance.

Heads up

If your team grows past ~50 people or you take on healthcare clients, you'll need SOC 2 readiness. Document these controls now — it's much easier to build the audit trail from day one than retrofit it later.

Chapter 06

Wiring it to Zapier & Twilio.

You already have Zapier and Twilio in your stack. Here's how they slot into this system:

Zapier as the nudge executor

Your API's event bus posts to a Zapier catch hook. Zapier branches on the event type (document.uploaded, stage.stalled, etc.) and fans out to the right channel — Gmail for emails, Twilio for SMS, Slack for team pings. The nudge-rules page (previous build) already outputs the exact payload format Zapier expects.

Twilio for SMS

Skip Zapier as the middleman for SMS if you're sending at volume — Twilio's API is cheap and reliable, and you can call it directly from your webhook handler. Use Twilio Studio for anything conversational (e.g., SMS-based "reply YES to confirm your start date").

// Direct Twilio call from webhook handler
POST https://api.twilio.com/2010-04-01/Accounts/{SID}/Messages.json
{
  "To": "+15551234567",
  "From": "+15559876543",
  "Body": "Hi Anthony, your I-9 is still pending..."
}

Notion sync (optional but useful)

Since your team runs on Notion, a nightly Zap can mirror the hires table into a Notion database so the team can comment, assign owners, or triage from inside the tool they already use.

Chapter 07

Launch checklist.

When you're ready to flip this from prototype to production, walk through these in order:

Pick storage backend — Drive, S3, or Supabase. Create the bucket/folder structure.
Set up the database schema — hires, documents, tasks, events tables.
Build the 8 API endpoints listed in Chapter 04.
Add authentication — magic-link email login is simplest; each hire gets a unique portal URL.
Wire the portal to the real API — replace window.storage calls with fetch() to your endpoints.
Connect the event bus to Zapier — one catch hook, branch by event type.
Test with one real hire before rolling out widely. End-to-end: invite → upload → nudge → complete.
Document the retention & deletion policy — put it somewhere the team can find it.
Set up monitoring — failed uploads, stuck hires, missing documents. Alert yourself.
Audit your first 10 hires — any confusion, friction, or drop-offs feed back into v2.
Scope guidance

If you're the only engineer on this, a realistic build timeline is 2 weeks for MVP (Drive + a thin Next.js API + basic auth), 4–6 weeks if you want polished admin tooling, retention automation, and the full Zapier flow. Start small and ship.