0
stars
312
commits
TypeScript
primary language
Aug 17, 2026
updated
Personal portfolio and private photo archive built with Next.js. The site has a public entry page, resume and portfolio routes, an authenticated admin area, Supabase-backed picture data, Cloudflare R2/S3-compatible image uploads, AI-assisted image analysis/translation, and semantic picture search.
app/ Next.js routes and API handlers
components/ UI and portfolio/admin components
components/ui/ Shared primitive UI components
data/ Static portfolio seed data
docs/ Supabase SQL and feature notes
hooks/ React hooks
lib/ Shared app utilities and domain helpers
public/ Public images and static assets
scripts/ Backfill/debug scripts and embedding service tools
utils/ Supabase, R2, auth, and server helpers
Enable pnpm with Corepack if needed:
corepack enable
corepack prepare pnpm@latest --activate
git clone https://github.com/Cunyli/PrivateWeb.git
cd PrivateWeb
pnpm install
cp .env.example .env
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
NEXT_PUBLIC_BUCKET_URL=
ADMIN_EMAILS=
NEXT_PUBLIC_ADMIN_EMAILS=
pnpm dev
Open http://localhost:3000.
The full template is in .env.example. Keep real values in .env locally or in your deployment provider's secret manager.
Required for the core site:
NEXT_PUBLIC_SUPABASE_URL: Supabase project URL.NEXT_PUBLIC_SUPABASE_ANON_KEY: Supabase browser anon key.SUPABASE_SERVICE_ROLE_KEY: Server-only key used by admin API routes and scripts.NEXT_PUBLIC_BUCKET_URL: Public base URL for image assets.ADMIN_EMAILS: Comma-separated admin email allowlist for server checks.NEXT_PUBLIC_ADMIN_EMAILS: Comma-separated admin email allowlist used by client-side admin UI.Required for uploads:
R2_ENDPOINT_URLR2_BUCKET_NAMER2_ACCESS_KEY_IDR2_SECRET_ACCESS_KEYOptional AI configuration:
OPENAI_API_KEY, OPENAI_VISION_MODEL, and OPENAI_TRANSLATION_MODEL for OpenAI.AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_API_KEY, AZURE_OPENAI_API_VERSION, and AZURE_OPENAI_DEPLOYMENT for Azure OpenAI.JINA_API_KEY, JINA_EMBEDDING_MODEL, JINA_EMBEDDING_DIMENSIONS, and SEMANTIC_EMBEDDING_PROVIDER for semantic picture search.TEXT_EMBEDDING_API_URL and/or IMAGE_EMBEDDING_API_URL.Run the SQL files in docs/ from the Supabase SQL Editor as needed:
docs/supabase-policies.sql: row-level security policies.docs/add-location-translations.sql: multilingual location fields.docs/add-image-variants.sql: image variant metadata.docs/upgrade-picture-embeddings-1024.sql: 1024-dimensional vector embeddings and matching RPC.docs/ai-tasks.sql: private AI/work task table used by the authenticated /ai-feed workspace.Semantic search also depends on the picture_embeddings table and match_pictures_by_embedding RPC described in docs/semantic-picture-search.md.
pnpm dev
pnpm build
pnpm start
pnpm lint
pnpm backfill:picture-embeddings -- --limit 3 --dry-run
Use the backfill command only after Supabase and embedding credentials are configured. For a production backfill, read docs/semantic-picture-search.md first.
The easiest deployment target is Vercel:
main branch.Before publishing the repository publicly, review public/private/ and any committed images to make sure they are intended to be visible.
.env, .vercel/, .next/, node_modules/, logs, test output, or TypeScript build info..env.example updated whenever a new environment variable is added.docs/ together with the SQL migration..gitignore:git rm --cached .DS_Store tsconfig.tsbuildinfo
301 commits
11 commits
TypeScript
95.6%
JavaScript
2.7%
0
stars
312
commits
TypeScript
primary language
Aug 17, 2026
updated
Personal portfolio and private photo archive built with Next.js. The site has a public entry page, resume and portfolio routes, an authenticated admin area, Supabase-backed picture data, Cloudflare R2/S3-compatible image uploads, AI-assisted image analysis/translation, and semantic picture search.
app/ Next.js routes and API handlers
components/ UI and portfolio/admin components
components/ui/ Shared primitive UI components
data/ Static portfolio seed data
docs/ Supabase SQL and feature notes
hooks/ React hooks
lib/ Shared app utilities and domain helpers
public/ Public images and static assets
scripts/ Backfill/debug scripts and embedding service tools
utils/ Supabase, R2, auth, and server helpers
Enable pnpm with Corepack if needed:
corepack enable
corepack prepare pnpm@latest --activate
git clone https://github.com/Cunyli/PrivateWeb.git
cd PrivateWeb
pnpm install
cp .env.example .env
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
NEXT_PUBLIC_BUCKET_URL=
ADMIN_EMAILS=
NEXT_PUBLIC_ADMIN_EMAILS=
pnpm dev
Open http://localhost:3000.
The full template is in .env.example. Keep real values in .env locally or in your deployment provider's secret manager.
Required for the core site:
NEXT_PUBLIC_SUPABASE_URL: Supabase project URL.NEXT_PUBLIC_SUPABASE_ANON_KEY: Supabase browser anon key.SUPABASE_SERVICE_ROLE_KEY: Server-only key used by admin API routes and scripts.NEXT_PUBLIC_BUCKET_URL: Public base URL for image assets.ADMIN_EMAILS: Comma-separated admin email allowlist for server checks.NEXT_PUBLIC_ADMIN_EMAILS: Comma-separated admin email allowlist used by client-side admin UI.Required for uploads:
R2_ENDPOINT_URLR2_BUCKET_NAMER2_ACCESS_KEY_IDR2_SECRET_ACCESS_KEYOptional AI configuration:
OPENAI_API_KEY, OPENAI_VISION_MODEL, and OPENAI_TRANSLATION_MODEL for OpenAI.AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_API_KEY, AZURE_OPENAI_API_VERSION, and AZURE_OPENAI_DEPLOYMENT for Azure OpenAI.JINA_API_KEY, JINA_EMBEDDING_MODEL, JINA_EMBEDDING_DIMENSIONS, and SEMANTIC_EMBEDDING_PROVIDER for semantic picture search.TEXT_EMBEDDING_API_URL and/or IMAGE_EMBEDDING_API_URL.Run the SQL files in docs/ from the Supabase SQL Editor as needed:
docs/supabase-policies.sql: row-level security policies.docs/add-location-translations.sql: multilingual location fields.docs/add-image-variants.sql: image variant metadata.docs/upgrade-picture-embeddings-1024.sql: 1024-dimensional vector embeddings and matching RPC.docs/ai-tasks.sql: private AI/work task table used by the authenticated /ai-feed workspace.Semantic search also depends on the picture_embeddings table and match_pictures_by_embedding RPC described in docs/semantic-picture-search.md.
pnpm dev
pnpm build
pnpm start
pnpm lint
pnpm backfill:picture-embeddings -- --limit 3 --dry-run
Use the backfill command only after Supabase and embedding credentials are configured. For a production backfill, read docs/semantic-picture-search.md first.
The easiest deployment target is Vercel:
main branch.Before publishing the repository publicly, review public/private/ and any committed images to make sure they are intended to be visible.
.env, .vercel/, .next/, node_modules/, logs, test output, or TypeScript build info..env.example updated whenever a new environment variable is added.docs/ together with the SQL migration..gitignore:git rm --cached .DS_Store tsconfig.tsbuildinfo
301 commits
11 commits
TypeScript
95.6%
JavaScript
2.7%