Skip to main content

How RestaPro works under the hood

For technical restaurant owners, partners, or anyone who wants to understand the architecture without reading code.

Stack in one image

Internet (HTTPS)
v
Traefik (TLS, rate limit 100 req/s + burst)
v
nginx (gzip, immutable cache, security headers)
v
React 19 + TypeScript (static build)
v
Supabase (PostgreSQL + Edge Functions + Auth + Storage)

Static frontend served by nginx, no traditional application server. Anything that isn't UI runs in Edge Functions Deno or in PostgreSQL via RLS.

Frontend

  • React 19 + TypeScript + Vite.
  • Static build compiled to HTML+JS+CSS with hashed names (cached forever).
  • Tailwind CSS 4 with oklch() tokens.
  • shadcn/ui + base-nova as the component system.
  • Served by nginx on :8090.
  • TanStack React Query for server state.
  • React Hook Form + Zod for forms.

Backend: Supabase

  • Managed PostgreSQL in Frankfurt (EU). GDPR-compliant by design.
  • Edge Functions Deno: ~60 serverless functions running on demand.
  • Auth: JWT with refresh tokens, email+password + Google OAuth.
  • Storage: for logos, covers, menu images.
  • Realtime: instant notifications via WebSocket.
  • pg_cron: scheduled tasks (email cron, proposal expiration, etc.).

Multi-tenant security: Row Level Security (RLS)

Every table with customer data has RLS policies that filter rows by logged-in user at the PostgreSQL layer:

USING (workspace_id IN (
SELECT workspace_id FROM workspace_users
WHERE user_id = auth.uid()
))

Even if someone hijacked a session, the database rejects cross-workspace queries. It's security at the DBMS level, not the application level.

Encryption

  • In transit: HTTPS/TLS 1.3 with Let's Encrypt certificates automated by Traefik.
  • At rest: PostgreSQL encrypts the volume.
  • Passwords: bcrypt (not reversible).
  • Secrets (Stripe API key, Gemini key, Resend, etc.): in Supabase Vault, not in .env or in the repository.

AI: Gemini + Pinche

  • Google's Gemini 2.5 Flash with function calling.
  • Pinche: 25 tools (10 write + 15 read).
  • Each call is logged in pinche_chat_logs for audit.
  • Google's Vertex AI policy: data is not used to train models.

Notifications

Realtime (instant)

When an online reservation comes in, every team device receives a real-time toast via Supabase Realtime (WebSocket over PostgreSQL CDC).

Transactional email (Resend)

  • Sending of confirmations, reminders, alerts, campaigns.
  • Idempotency in webhooks (resend_processed_events): if Resend re-sends due to timeout, it's processed only once.
  • Email logs auditable: each send with timestamp, status, tokens.
  • List-Unsubscribe headers RFC 5322 so Gmail offers one-click unsubscribe.

Payments: Stripe

  • Subscriptions managed by Stripe Billing.
  • Checkout Session + Customer Portal for payments and self-service.
  • Webhooks with idempotency check (stripe_processed_events).
  • RestaPro does not store cards - only Stripe Customer ID and Subscription ID.

Hosting

  • Supabase: AWS Frankfurt (EU). Replication + daily backups with 30-day retention.
  • CDN: Cloudflare for static assets.
  • Edge Functions: server latency close to the user.

GDPR

  • Data in Frankfurt, no transfers outside the EU without safeguards.
  • Right to be forgotten via the gdpr_delete_customer RPC: anonymizes name, email, phone in customers, customer_identities, email_logs, email_queue, marketing_*. Keeps reservations for audit/accounting.
  • Full audit in activity_logs.
  • More in Privacy and GDPR.

Backup and recovery

  • Daily Supabase backups automatic (30-day retention).
  • Geographic replication.
  • In case of accidental deletion: contact Supabase support to restore from a specific backup (RTO ~4 h).

Monitoring

  • Sentry: frontend error capture with userId + restaurant_id as tags. Anti-bot filters.
  • Structured logs in edge functions via createLogger with metadata.
  • Activity log in DB for sensitive actions (role changes, GDPR delete, etc.).

CI/CD

  • GitHub Actions runs lint + typecheck + tests + build on every push.
  • HTTP smoke tests post-deploy: if they fail, we abort.
  • Snapshots of the last 10 builds in /opt/backups/restapro-dist/ for fast rollback.

Continuous deployment

  • Every commit on main can reach production after manual review.
  • Build ID = git SHA, visible in <meta name="restapro:build-id">.
  • No semantic versioning - changes flow continuously.

More in Versioning and releases.

ESENCA