Skip to content
akram0zakiPublic

About

An AI-assisted interactive CV to help job seekers present their profile and work experience.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Profiley

An open-source, AI-powered interactive CV platform — turn your career history into a recruiter-facing public profile with retrieval-augmented chat and structured job-fit analysis.

License: AGPL v3 Docs: CC BY 4.0 Made with React Powered by Supabase Deployed on Cloudflare Pages

Profiley lets candidates upload their CV and supporting documents, automatically extracts and indexes them into a searchable knowledge base, and exposes a polished public profile that recruiters can browse, chat with, and run job-fit analysis against — all backed by transparent, admin-managed AI model routing.


Table of Contents


Highlights

  • 🧠 Retrieval-augmented chat over your own documents using pgvector and an admin-managed model registry (OpenAI, Gemini, Mistral).
  • 📄 Document ingestion pipeline with signed uploads, background processing, chunking, and embeddings — all in Supabase Edge Functions.
  • 🌐 Public recruiter profile with shareable slug, gated contact form, live persona chat, and structured job-fit analysis.
  • 📊 Owner dashboard with live analytics: recruiter visits, events, conversations, uploads, and job-fit runs.
  • 🛡️ Row-Level Security everywhere — multi-tenant data is RLS-scoped from day one.
  • ☁️ One-command deploys to Cloudflare Pages (frontend) and Supabase (schema + edge functions).

Feature Status

Implemented

  • ✅ Authentication: Google, GitHub, and email magic link
  • ✅ Profile management: editable profile, preferences, visibility, and shareable public slug
  • ✅ Document upload: signed upload URLs, storage, processing status, deletion, and knowledge chunk generation
  • ✅ Knowledge base: direct chunk browsing plus retrieval over vectorized knowledge
  • ✅ AI chat: recruiter-facing persona chat backed by edge functions, with citations
  • ✅ Job-fit analysis: structured analysis persisted to the database
  • ✅ Public profile: live recruiter view, activity tracking, and gated contact/chat/job-fit features
  • ✅ Dashboard: live analytics from recruiter visits, events, conversations, uploads, and job-fit runs
  • ✅ Settings and admin: privacy controls, persona tone, model registry, feature-to-model assignment, and provider health
  • ✅ Cloudflare Pages deployment: dev and prod workflows

Roadmap

  • 🔜 Live AI avatar generation
  • 🔜 Real-time voice conversations with AI
  • 🔜 Apple OAuth
  • 🔜 Per-user model overrides
  • 🔜 Full observability and test hardening (pgTAP, k6, Sentry/PostHog)

Technology Stack

Frontend

  • React 18 · React Router 7 · TypeScript
  • Vite 6 · Tailwind CSS v4
  • Radix UI + shadcn/ui patterns · Sonner

Backend & infrastructure

  • Supabase: Auth, Postgres, Storage, Edge Functions (Deno)
  • pgvector for embeddings and RAG
  • Cloudflare Pages + Wrangler
  • AI provider routing across OpenAI, Gemini, and Mistral via admin-managed configs

Architecture Overview

                 ┌────────────────────────┐
                 │  Cloudflare Pages      │
                 │  React SPA (Vite)      │
                 └──────────┬─────────────┘
                            │  HTTPS
                            ▼
   ┌────────────────────────────────────────────────┐
   │               Supabase Project                 │
   │                                                │
   │  Auth                                          │
   │   │                                            │
   │   ▼                                            │
   │  Postgres (RLS)  ◄──►  Edge Functions (Deno)   │
   │   │                         │                  │
   │   ▼                         ▼                  │
   │  pgvector            AI providers              │
   │                      (OpenAI / Gemini /        │
   │                      Mistral, admin-routed)    │
   │                                                │
   │  Storage — signed uploads & documents          │
   └────────────────────────────────────────────────┘

See docs/concept/ and docs/flows/ for deeper design notes and flow diagrams.

Project Structure

apps/
  frontend/                  # React SPA (Vite, Tailwind, shadcn/ui)
    src/app/                 # Pages, components, contexts
    src/lib/                 # Shared client utilities
    functions/               # Cloudflare Pages functions
    test/                    # Vitest specs
supabase/
  migrations/                # Versioned SQL migrations (RLS, schema, seeds)
  functions/                 # Deno edge functions (one folder per function)
  tests/                     # Deno tests for edge functions
docs/
  DESIGN_SYSTEM.md
  I18N_RTL_GUIDE.md
  testing.md
  concept/                   # Product design, PRD, init guide
  flows/                     # Mermaid diagrams for ingestion, chat, etc.

Pages and Routes

Route Purpose
/ Marketing landing page
/login Sign-in with Google, GitHub, or magic link
/auth/callback OAuth / magic-link callback
/onboarding Multi-step profile setup persisted to Supabase
/dashboard Owner dashboard with live analytics
/profile Profile editor
/uploads Document upload and processing management
/knowledge Knowledge chunk browser
/chat-preview Owner-side chat preview
/job-fit-preview Owner-side job-fit preview
/public/:username Public recruiter-facing profile
/settings Account and privacy settings
/settings/ai Persona and model summary
/settings/avatar Placeholder for the future avatar workflow
/admin Admin-only provider registry and health dashboard

Getting Started

Prerequisites

  • Node.js 20+
  • pnpm 9+
  • A Supabase project (free tier is fine for local development)
  • Populated env files:
    • apps/frontend/.env.development — local/dev frontend builds
    • apps/frontend/.env.production — production frontend builds
    • supabase/.env — Supabase CLI work (project refs, DB password)
    • supabase/functions/.env.development / .env.production — edge function secrets
    • .github/.env.ci — Cloudflare deploys

See supabase/functions/.env.example and docs/concept/profiley-init-guide.md for the full list of required keys.

Install

git clone https://github.com/akram0zaki/profiley.git
cd profiley
pnpm install

Run locally

pnpm dev

This runs the Vite app from apps/frontend against apps/frontend/.env.development.

Test

pnpm test            # frontend (Vitest) + edge (Deno) tests
pnpm test:frontend   # Vitest only
pnpm test:edge       # Deno tests in supabase/tests/

Testing strategy and conventions are documented in docs/testing.md.

Build

pnpm build       # development build (apps/frontend/dist)
pnpm build:prod  # production build
pnpm preview     # preview the built bundle

Useful Scripts

Run from the repository root:

Script Description
pnpm dev Run the frontend locally in development mode
pnpm build / pnpm build:prod Build the SPA in development / production mode
pnpm preview Preview the built frontend bundle
pnpm test Run frontend and edge tests
pnpm run ci Run every CI check locally (build + deno check + tests)
pnpm run ci:edge Type-check every edge function, as CI does
pnpm run deploy Build and deploy to the dev Cloudflare Pages project
pnpm deploy:prod Build and deploy to the prod Cloudflare Pages project

CI checks on push

pnpm install points core.hooksPath at .githooks, whose pre-push hook runs pnpm run ci — the same three checks GitHub Actions runs on a PR, so a push fails locally instead of on the PR:

  1. ci:build — production build of the SPA
  2. ci:edge — deno check on every supabase/functions/*/index.ts
  3. pnpm test — Vitest plus Deno tests

Both the hook and the workflow call scripts/ci-edge-check.sh, so there is one definition of the edge check. It runs from supabase/: from the repo root Deno resolves the root package.json and fails on missing npm type packages.

Skip the hook for a single push with git push --no-verify. If hooks are not active (a clone that never ran pnpm install), enable them with git config core.hooksPath .githooks.

Deployment

There are two environments, each a Supabase project paired with a Cloudflare Pages project:

Environment Supabase project Pages project Vite mode Edge secrets file
dev (staging) $SUPABASE_PROJECT_REF_DEV $CLOUDFLARE_PAGES_PROJECT_DEV (e.g. profiley-dev) development supabase/functions/.env.development
prod $SUPABASE_PROJECT_REF_PROD $CLOUDFLARE_PAGES_PROJECT_PROD (e.g. profiley) production supabase/functions/.env.production

Always deploy the backend before the frontend, so the new UI never calls functions or columns that are not there yet. Run pnpm test first.

Local deploys ship your working tree, not git — uncommitted changes and untracked migrations are included. The GitHub Actions workflow only deploys what is pushed to main.

1. Backend → Supabase

Schema and edge functions are managed entirely through workspace files (supabase/migrations/*.sql and supabase/functions/<name>/index.ts) — never via the dashboard.

set -a && source supabase/.env && set +a

# Schema
supabase link --project-ref "$SUPABASE_PROJECT_REF_DEV"
supabase db push --password "$SUPABASE_DB_PASSWORD_DEV"

# Edge function secrets (idempotent)
supabase secrets set \
  --project-ref "$SUPABASE_PROJECT_REF_DEV" \
  --env-file supabase/functions/.env.development

# Edge functions (all of them)
for fn in supabase/functions/*/; do
  name=$(basename "$fn")
  [[ "$name" == "_shared" ]] && continue
  supabase functions deploy "$name" --project-ref "$SUPABASE_PROJECT_REF_DEV" --no-verify-jwt
done

For production, use the _PROD variables and supabase/functions/.env.production.

--no-verify-jwt is required: public and cron-driven functions receive no JWT, and authenticated ones validate it themselves via requireUser(). Do not run supabase login — the CLI authenticates with the SUPABASE_ACCESS_TOKEN in supabase/.env.

2. Frontend → Cloudflare Pages

pnpm run deploy    # dev (staging) project — plain `pnpm deploy` is a pnpm built-in and fails
pnpm deploy:prod   # prod project

Each deploy script sources .github/.env.ci, builds with the matching Vite mode (reading apps/frontend/.env.development or .env.production), and publishes apps/frontend/dist via Wrangler. Required variables in .github/.env.ci:

  • CLOUDFLARE_API_TOKEN
  • CLOUDFLARE_ACCOUNT_ID
  • CLOUDFLARE_PAGES_PROJECT_DEV
  • CLOUDFLARE_PAGES_PROJECT_PROD

The Pages Functions runtime variables (SUPABASE_URL, SUPABASE_ANON_KEY, PUBLIC_APP_ORIGIN) are set once per Pages project in the Cloudflare dashboard; wrangler pages deploy does not upload them.

Alternative for prod: GitHub Actions

The manual deploy workflow (.github/workflows/deploy.yml) is prod-only: it pushes migrations, deploys every edge function, then builds and publishes the frontend. Trigger it from the Actions tab or with gh workflow run deploy.yml. It never runs on push, does not sync edge function secrets, and needs the repo secrets listed in the init guide.

After deploying

Run the smoke test in docs/concept/profiley-init-guide.md §8. The same guide covers first-time setup (creating the Pages projects, auth providers, cron secret) and the full deploy checklist.

Documentation

Security

For production use with real user data:

  • Keep secrets in the gitignored env files documented in AGENTS.md. Never put secrets in VITE_* variables — those are inlined into the public client bundle.
  • Apply schema changes through supabase/migrations/ and verify Row-Level Security policies on every change.
  • Rotate the Supabase DB password and provider API keys before opening the project to external traffic.
  • Found a vulnerability? Please open a private security advisory via GitHub rather than a public issue.

Contributing

Contributions are welcome — see CONTRIBUTING.md for the full policy. In short:

  • Code is contributed under AGPL-3.0-or-later.
  • Documentation is contributed under CC BY 4.0.
  • The Profiley name, logo, and branding are not licensed for reuse — see TRADEMARKS.md.
  • Follow the workspace conventions in AGENTS.md and the runtime-specific instructions under .github/instructions/.
  • Add or update tests for every functional change and update CHANGELOG.md for meaningful product or operational changes.

License and Attribution

  • Source code: GNU Affero General Public License v3.0 or later. If you modify and run Profiley as a network service, you must make the corresponding source code available to its users.
  • Documentation and written content: Creative Commons Attribution 4.0 International, unless otherwise noted.
  • Branding and trademarks: the Profiley name, logo, and visual identity are reserved — see TRADEMARKS.md.
  • Third-party notices and credits live in NOTICE and ATTRIBUTIONS.md.

Copyright © 2026 Akram Zaki.


Built with React, Supabase, and Cloudflare. Last updated: April 28, 2026.

About

An AI-assisted interactive CV to help job seekers present their profile and work experience.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages