One central health record for your pet, shared with any vet as a secure, read-only, AI-summarized snapshot.
Live app: https://pet-pass-xi.vercel.app/ Β Β·Β Stack: React 19 Β· Vite Β· Tailwind Β· Supabase Β· Anthropic Claude Β· Vercel
PetPass lets a pet owner keep their pet's complete health history in one place β profile, vaccinations, medications, allergies, chronic conditions, lab results, treatments, and personal observations. With one click the owner generates an AI-written professional summary and shares it with a vet through a secure link or QR code β read-only, time-limited, and revocable at any time.
When a pet needs care at a new or emergency clinic, the vet has no access to prior history. This causes real harm:
- π Repeated, unnecessary diagnostic tests
β οΈ Missed drug allergies and interactions- β±οΈ Slower, less-informed treatment decisions
- πΈ Higher insurance payouts from avoidable exams
Today owners cope by digging through paper folders, re-requesting records from old clinics, or trying to recall history from memory during a stressful emergency. PetPass removes that friction by giving the vet an instant, organized, AI-summarized snapshot of the pet.
| Who | When they use it | What they do |
|---|---|---|
| Pet owners | Ongoing β building the record over time | Add pets, upload documents by category, log observations, generate a summary, share a link |
| Vets (no account needed) | At the point of care / emergency | Open a shared link or scan a QR code β view a read-only summary + documents |
The vet never creates an account and can never edit anything β access is gated entirely by a secure token.
Anything the owner uses today to carry health history counts as a competitor:
| Existing approach | Why it falls short |
|---|---|
| Paper folder / re-faxing records between clinics | Slow, easily lost, nothing to hand a vet in an emergency |
| Owner's memory + WhatsApp / email to the vet | Unstructured, incomplete, error-prone under stress |
| Clinic-locked EMRs (e.g. ezVet, Provet Cloud) | Data lives with one clinic β it doesn't travel with the pet or the owner |
| Generic cloud storage (Google Drive, Photos) | Just a pile of files β no structure, no summary, no safe sharing |
How PetPass is different:
- π§ Owner-owned single source of truth β the record follows the pet, not the clinic.
- π€ AI-summarized, not raw dumps β the vet reads a professional summary, not 20 PDFs.
- π Secure, revocable sharing β links expire and can be revoked; the vet gets no permanent copy.
- β‘ Zero-friction vet access β QR code or link, no login, built for the emergency handoff.
Live app: https://pet-pass-xi.vercel.app/
Demo credentials:
Email: georgy1230@gmail.com
Password: Aa12345678
Try the core flow in ~2 minutes: Log in β Overview β Records (see/upload documents) β Notes (owner observations) β Share β Generate Summary β copy the share link / QR β open it in a private window to see the read-only vet view.
The owner reviews the AI-generated vet summary, key health cards, and shares it with a time-limited link or QR code β revocable at any time.
Opening the share link lands the vet on a read-only view: pet profile, AI medical summary, key health overview, owner notes, and downloadable documents. No account, no editing.
Contact phone numbers in these screenshots are intentionally masked.
Owner
- Sign up / log in (email + password).
- Create a pet profile (type, breed, birth date, sex, sterilization, identifiers).
- Upload medical documents and categorize them (vaccination, lab result, prescription, treatment, surgery, general).
- Add structured owner notes (appetite, vomiting, stool, behavior, free text).
- Click Generate Summary β the AI produces a professional vet-facing summary.
- Create a share link, optionally set an expiry, share the link/QR, and revoke whenever needed.
Vet
- Open the shared link or scan the QR code β land on
/vet/:token(no login). - Read a read-only summary: pet details, AI summary, key health cards, documents.
- Download allowed documents via short-lived signed URLs. No account, no editing.
| Screen | Route | Auth | Purpose |
|---|---|---|---|
| Landing | / |
Public | Marketing page + login/register CTAs |
| Login | /login |
Public | Email/password sign-in |
| Sign up | /signup |
Public | Account + first pet creation |
| Overview | /overview |
Owner | Health summary cards (allergies, meds, vaccines, treatments, notes) |
| Medical Records | /records |
Owner | Upload / categorize / preview documents |
| Notes | /notes |
Owner | Add & list structured observations |
| Share / Vet Summary | /share |
Owner | Generate AI summary + manage share link, QR, expiry, revoke |
| Vet Shared View | /vet/:token |
Token-gated | Read-only vet view |
| Layer | Technology |
|---|---|
| Frontend | React 19, Vite, Tailwind CSS 3 |
| Routing | React Router 7 |
| UI | lucide-react (icons), react-qr-code |
| Testing | Vitest + jsdom |
| Auth / DB / Storage | Supabase (Postgres 17 + Auth + Storage) |
| Server logic | Supabase Edge Functions (Deno) |
| AI | Anthropic Claude |
| Hosting | Vercel (frontend SPA) |
PetPass has no traditional backend server. The browser talks to Supabase directly using the public anon key (protected by Row Level Security), and anything that needs a secret key or must be trusted runs inside Supabase Edge Functions.
- Sign-up / login via
supabase.auth(email + password). A database trigger creates the matchingowner_profilerow on sign-up. - The browser only ever holds
VITE_SUPABASE_ANON_KEY. Row Level Security scopes every row toauth.uid(), so users can only read/write their own data.
- React context providers (
petContext,healthRecordsContext,notesContext) read and write through the anon Supabase client. - Documents are uploaded to the private
medical-documentsbucket, path{owner_id}/{pet_id}/{uuid}-{filename}, and served to the browser via 1-hour signed URLs (src/lib/storageService.js). Files are never public.
- Owner clicks Generate Summary; the function verifies the caller owns the pet.
- It claims a per-pet lock (advisory lock via RPC) so only one generation runs at a time.
- It summarizes each document, then the notes, then writes a final overall summary using Claude β caching each result by a content hash to skip redundant work.
- Results are written to
document_summaries,notes_summaries, andai_summaries; the frontend polls the status until it's complete. - The AI key (
AI_API_KEY) lives only inside the Edge Function β it never reaches the browser.
- The share token is validated server-side: the link must exist, be not revoked
(
revoked_at IS NULL), and not expired (expires_at > now()). vet-overviewreturns a read-only bundle (pet + AI summary + health cards);vet-documentsreturns short-lived signed URLs for the shared documents. Token validation never happens in client-side React.
Data model from the live Supabase project (public schema). The two hubs are
owner_profile (its id = the Supabase auth user) and pet.
erDiagram
owner_profile ||--o{ pet : owns
owner_profile ||--o{ medical_records : owns
owner_profile ||--o{ owner_note : owns
owner_profile ||--o{ vet_share_link : owns
owner_profile ||--o{ ai_summaries : owns
owner_profile ||--o{ document_summaries : owns
owner_profile ||--o{ notes_summaries : owns
owner_profile ||--o{ vet_summary : owns
pet_type ||--o{ pet_breed : has
pet_type ||--o{ pet : classifies
pet_breed ||--o{ pet : classifies
pet ||--o{ medical_records : has
pet ||--o{ owner_note : has
pet ||--o{ vet_share_link : shared_via
pet ||--o{ document_summaries : has
pet ||--o| ai_summaries : has
pet ||--o| notes_summaries : has
pet ||--o{ vet_summary : has
medical_record_category ||--o{ medical_records : categorizes
medical_records ||--o| document_summaries : summarized_as
ai_status_types ||--o{ ai_summaries : status
ai_status_types ||--o{ document_summaries : status
ai_status_types ||--o{ notes_summaries : status
owner_profile {
uuid id PK
text first_name
text last_name
text email
text phone
text avatar_url
}
pet {
bigint id PK
uuid owner_id FK
bigint pet_type_id FK
bigint breed_id FK
text name
timestamp birth_date
text sex
boolean is_sterilized
jsonb identifiers
jsonb type_attributes
boolean is_active
}
pet_type {
bigint id PK
text name
text display_name
jsonb default_fields
boolean is_active
}
pet_breed {
bigint id PK
bigint pet_type_id FK
text name
text display_name
boolean is_active
}
medical_record_category {
bigint id PK
text name UK
text display_name
boolean supports_expiry_date
boolean is_active
}
medical_records {
bigint id PK
bigint pet_id FK
uuid owner_id FK
bigint category_id FK
text title
text description
timestamptz record_date
timestamptz expiry_date
text storage_path
text mime_type
text file_hash
boolean is_ai_summary_supported
boolean is_active
}
owner_note {
bigint id PK
bigint pet_id FK
uuid owner_id FK
text title
text free_text
text appetite
boolean vomiting
text stool
text behavior
timestamptz observed_at
boolean is_active
}
vet_share_link {
bigint id PK
bigint pet_id FK
uuid owner_id FK
text token
timestamptz expires_at
timestamptz revoked_at
}
ai_summaries {
bigint id PK
bigint pet_id FK "unique"
uuid owner_id FK
smallint status_id FK
text summary_text
text source_hash
timestamptz generated_at
}
document_summaries {
bigint id PK
bigint medical_record_id FK "unique"
bigint pet_id FK
uuid owner_id FK
smallint status_id FK
text summary_text
text source_hash
timestamptz generated_at
}
notes_summaries {
bigint id PK
bigint pet_id FK "unique"
uuid owner_id FK
smallint status_id FK
text summary_text
text source_hash
timestamptz generated_at
}
ai_status_types {
smallint id PK
text name UK
}
ai_prompts {
bigint id PK
text key UK
text prompt_text
text description
}
vet_summary {
bigint id PK
bigint pet_id FK
uuid owner_id FK
text summary_text
timestamptz generated_at
}
Note:
vet_summaryis a legacy table kept for reference; the active AI pipeline usesai_summaries(final summary) together withdocument_summariesandnotes_summaries(per-source caches).ai_promptsstores editable prompt templates andai_status_typesis a status lookup (generating/complete/error).
| Service | Type | Role in the product |
|---|---|---|
| Supabase Auth | Authentication | Email/password sign-up & login; session / JWT management |
| Supabase Postgres + RLS | Database | Stores all app data; Row Level Security scopes every row to its owner |
| Supabase Storage | File storage | Private medical-documents bucket + pet avatars, served via signed URLs |
| Supabase Edge Functions (Deno) | Serverless / server logic | generate-summary, vet-overview, vet-documents β hides keys, validates share tokens server-side |
| Anthropic Claude | AI API | Summarizes documents, notes, and produces the overall vet summary (server-side only) |
| Vercel | Hosting / deployment | Builds and serves the React single-page app |
Client-side (safe to expose β used by the browser):
| Variable | Description |
|---|---|
VITE_SUPABASE_URL |
Supabase project URL |
VITE_SUPABASE_ANON_KEY |
Supabase public anon key (limited by RLS) |
Server-side only (Edge Function / Vercel secrets β never in src/ or any VITE_ variable):
| Variable | Description |
|---|---|
SUPABASE_SERVICE_ROLE_KEY |
Bypasses RLS; used only inside Edge Functions |
AI_API_KEY |
Anthropic Claude API key |
AI_MODEL |
Claude model id used for summaries |
π« The service role key and AI key must never appear in client-side code or in a
VITE_-prefixed variable. The only Supabase credential safe for the browser is the anon key.
# 1. Install dependencies
npm install
# 2. Create .env.local with your Supabase project values
# VITE_SUPABASE_URL=https://<your-project-ref>.supabase.co
# VITE_SUPABASE_ANON_KEY=<your-anon-key>
# 3. Start the dev server β http://localhost:5173
npm run dev
# Other commands
npm run build # Production build β dist/
npm run preview # Preview the production build
npm run lint # ESLintThe three Edge Functions run on Supabase (
supabase/functions/) and require the server-side secrets above to be set in the Supabase project.
src/
components/ # Reusable UI (shell, cards, forms, share, vet)
pages/ # One file per route/screen
lib/ # Supabase client, contexts, storage & helpers
hooks/ # Custom data-fetching hooks
supabase/
functions/ # Edge Functions: generate-summary, vet-overview, vet-documents
migrations/ # Timestamped SQL schema migrations
docs/ # Product, UI, backend & deployment specs


