Join the Agent Deck Discord Server!
Discord에서 Agent Deck 커뮤니티 확인, 357명과 자유 음성·텍스트 채팅 이용
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A digital group card app: one shareable link, multiple people add a note, photo, sticker, or drawing to a card in real time. No accounts, no sign-ups.README 전문 보기 ↗
A digital group card app: one shareable link, multiple people add a note, photo, sticker, or drawing to a card in real time. No accounts, no sign-ups.
Live at: https://warmly-alpha.vercel.app
postgres_changes)src/styles.css)jspdf + html2canvas (client-side only — rasterizes each face, assembles a real two-page PDF)api/feedback.js — the only write path for the feedback table (see below)The browser talks to Supabase directly with the anon/publishable key for every table except feedback, which has no client-facing RLS policies at all and can only be written through api/feedback.js (it needs the real request IP and Vercel's geo headers, neither of which exist client-side). The signature cap, the 14-day lifespan, and the daily card-creation limit are all enforced by Postgres triggers that can't be bypassed from the client; see DECISIONS.md.
api/feedback.js needs two server-only environment variables set in Vercel (not prefixed VITE_, so they never reach the browser bundle) — see .env.example: SUPABASE_SERVICE_ROLE_KEY and IP_HASH_SALT.
src/
CreateScreen.jsx "Start a card" form → creates a cards row
ShareScreen.jsx Shows the shareable link after creation
CardScreen.jsx The card canvas: notes, photos, stickers, drawing,
signing, realtime sync, upgrade/send/print flows
ObjectView.jsx Renders one canvas object from a prepared descriptor
lib/
supabase.js Supabase client (reads VITE_SUPABASE_URL / VITE_SUPABASE_ANON_KEY)
cardData.js All CRUD + realtime subscription + Storage upload calls
participant.js Local (localStorage) "who am I on this card" identity
canvasHtml.js Cover-template seeding + static HTML rendering (used for
the print/preview mock and PDF export)
stickers.js Sticker SVGs + cover color palette
api/
feedback.js Serverless function: the one write path for the feedback table
supabase/
migrations/0001_init.sql Full schema: tables, RLS policies, signature-cap
trigger, storage bucket + policies
migrations/0002-0009 Later schema changes — see each file's own comment
functions/
purge-expired-cards/ Scheduled Edge Function: hard-deletes cards (+ their
Storage photos) 15 days after creation
scripts/ One-off ops tools (pre-launch data wipe) — see
supabase/scripts/README.md; not part of the app
vercel.json SPA rewrite so /c/:id and /share/:id don't 404 on reload
npm install
cp .env.example .env # fill in your Supabase project URL + anon key
npm run dev
The dev server runs at http://localhost:5173.
The anon key can't run schema migrations. In the Supabase SQL Editor for your project, run:
supabase/migrations/0001_init.sql
This creates cards, signers, card_objects, RLS policies, the signature-cap trigger, and the card-photos storage bucket. It's idempotent-ish (create ... if not exists / on conflict) except for the create policy statements, which will error if run twice — if you need to re-run part of it, do so selectively.
| Variable | Where it's used |
|---|---|
VITE_SUPABASE_URL | src/lib/supabase.js |
VITE_SUPABASE_ANON_KEY | src/lib/supabase.js |
VITE_GA4_MEASUREMENT_ID | src/lib/analytics.js — optional; analytics load only when set and the build is production |
These are safe to expose client-side (that's what the anon/publishable key is for) — but still keep .env out of git (it already is, via .gitignore) and set them via your host's environment variable UI in production, not hardcoded.
GA4 (src/lib/analytics.js), loaded only in production and only when VITE_GA4_MEASUREMENT_ID is set — gtag.js is injected async so it never blocks first paint. Consent Mode v2 defaults to denied for all storage (there's no consent banner yet), so GA4 runs cookieless and models the gaps. Four custom events — card_created, card_shared, card_signed, feedback_submitted — fire at their success points; params are limited to non-PII (occasion, format, method, location, rating) and the card UUID is stripped from page_location/page_path on every hit. See DECISIONS.md ("GA4 analytics") for the full list of what is and isn't tracked, and register the event params as custom dimensions in the GA4 UI to see them in reports.
Hosted on Vercel, connected to the clementsim-studio/warmly GitHub repo. Framework preset auto-detects as Vite (npm run build, output dist). Set VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY as Environment Variables in the Vercel project before deploying. vercel.json handles the SPA rewrite; no other config needed.
purge-expired-cards — a Supabase Edge Function that permanently deletes each card 15 days after it was created (it's already frozen/read-only at 14 days by a DB trigger). It removes the card's photos from the card-photos bucket, then deletes the cards row; ON DELETE CASCADE clears its signers and card_objects. feedback rows are kept — their card_id/signer_id are set to null, and card_occasion/card_format are frozen onto each row at submission time for analytics. This is a hard, irreversible delete; the card's link 404s afterwards.
One-time setup (not covered by a Vercel deploy — Supabase-side):
supabase functions deploy purge-expired-cards (JWT verification left on).0008_feedback_survives_card_purge.sql in the SQL Editor.0009_schedule_purge_expired_cards.sql:
select vault.create_secret('https://<project-ref>.supabase.co', 'project_url');
select vault.create_secret('<service-role-key>', 'service_role_key');
Migration 0009 has the full prerequisite list and the queries to inspect cron.job_run_details afterwards.The function reads Supabase's auto-injected SUPABASE_URL / SUPABASE_SERVICE_ROLE_KEY — no manual function env vars.
unlimited: true to the database) and email sending (shows a toast, sends nothing).cards and signers rows can't be deleted via the anon key (no DELETE policy on those tables) — only card_objects rows can be removed by the client. This is incidental (not a deliberate feature) but worth knowing if you're cleaning up test data — you'll need SQL Editor access for those two tables. (The purge-expired-cards job deletes them server-side with the service-role key; that's a separate path from the anon client.)