Commit Graph
5 Commits
Author SHA1 Message Date
Omar SobhandClaude Opus 4.8 256f2285b9 "We Met" scan experience — capture connections on scan
CI / policy (push) Has been cancelled
CI / backend (push) Has been cancelled
CI / profile (push) Has been cancelled
CI / mobile (push) Has been cancelled
Experience #1 from the scan-experiences brief: when someone scans a card and
shares back, capture the meeting (with coarse geo + time) so the owner gets a
"People I met" list.

Backend (cardclaws-backend):
- migration 0006_connections.sql: connections table (card_id, owner_id, name,
  email, note, country, city, met_at). Raw IP never stored — only resolved geo.
- POST /v1/profile/:handle/connect (public, rate-limited 5/min): captures the
  connection with geo, emails the owner best-effort.
- GET /v1/cards/:id/connections (owner-only): the People-I-met list.
- ConnectionRow model + connections queries (insert, list_by_card);
  profile_service::submit_connection; card_service::list_connections.
- 2 tests (capture→owner-list + validation, owner-only); gate green (118 tests).
- Verified live end-to-end.

Web (cardclaws-profile):
- [handle].astro: a "We met?" share-back form posting to /connect; astro check
  clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-05 18:36:09 -05:00
Omar SobhandClaude Opus 4.8 5aba3ef1a1 AI Welcome scan experience — backend + web profile
CI / backend (push) Has been cancelled
CI / profile (push) Has been cancelled
CI / mobile (push) Has been cancelled
CI / policy (push) Has been cancelled
When a card is scanned, the public profile can open with a full-bleed,
AI-generated welcome hero before the contact info — experience #10 from the
scan-experiences brief, on the share-token experience selector foundation.

Backend (cardclaws-backend):
- migration 0005_welcome.sql: add cards.welcome JSONB; flows through
  PublicProfile via serde flatten.
- POST /v1/cards/:id/welcome (owner-gated): refine + generate via the existing
  AiClient (nano-banana), store {kind, message, imageDataUrl}.
- card_service::set_welcome + queries::update_welcome; CardRow gains `welcome`.
- 2 tests (generate→public-profile, ownership); workspace gate green (116 tests).
- Verified live with real Gemini end-to-end.

Web (cardclaws-profile):
- WelcomeHero.astro: full-bleed AI hero + greeting + "scroll to connect" cue.
- [handle].astro renders it when the card has a welcome; experience selector
  (?x=profile suppresses) as the lever for the other experiences.
- PublicProfile gains an optional `welcome`; astro check clean.

MVP inlines the image as a data URL; production swaps to an R2 URL (isolated in
the welcome column).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-05 18:21:27 -05:00
Omar SobhandClaude Opus 4.8 826ef69030 Phase 4 + GDPR: team analytics, central templates, account export/deletion
CI / policy (push) Successful in 9s
CI / mobile (push) Successful in 21s
CI / profile (push) Successful in 20s
CI / backend (push) Failing after 1m3s
Teams:
- GET /v1/teams/{id}/analytics (admin) — per-card visits/qr/saves/clicks across
  members, sortable (whitelisted columns); …/analytics.csv exports RFC-4180 CSV
- Central template library (migration 0004 team_templates):
  POST|DELETE /v1/teams/{id}/templates[/{templateId}] (admin), GET (member)

GDPR (§18.3):
- GET /v1/account/export — full JSON dump via Postgres json_agg (no password hash)
- DELETE /v1/account — hard delete, FK cascade removes all owned data

107 backend tests; fmt + clippy clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-04 16:15:39 -05:00
Omar SobhandClaude Opus 4.8 2b8e23dd3f Phase 4 backend: teams data layer + membership management
CI / backend (push) Failing after 1m6s
CI / policy (push) Successful in 4s
CI / profile (push) Successful in 12s
CI / mobile (push) Successful in 17s
- Migration 0003: teams + team_memberships (owner/admin/member, seat_limit)
- POST /v1/teams (Team-tier gated), GET /v1/teams/{id},
  GET|POST /v1/teams/{id}/members, DELETE …/members/{userId}
- Add-by-email (existing accounts), seat-cap enforcement (402), role-based
  authorization (admin to mutate; non-members get 404; owner unremovable)
- Invite notification email; Tier::can_own_team()

100 backend tests; fmt + clippy clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-04 15:13:03 -05:00
Omar SobhandClaude Opus 4.8 c30d3afeec Phase 1 foundation: backend, web profile, and mobile app
CI / policy (push) Successful in 0s
CI / mobile (push) Successful in 47s
CI / profile (push) Successful in 49s
CI / backend (push) Failing after 49s
Greenfield implementation of CardClaws Phase 1 across three surfaces.

Backend (Rust/Axum workspace, 67 tests):
- cardclaws-types/config/db/auth/api/wallet crates
- Auth: register, login + lockout, magic link, refresh rotation, Apple verify
- Cards: CRUD, tier-limited publish, duplicate, public handle lookup
- Assets: R2 presigned uploads; vCard export
- Apple Wallet .pkpass pipeline (PKCS#7 signer behind apple-signing feature)
- Analytics ingest + summary with daily-salted IP hashing
- Migrations 0001 (incl. cardclaws_sessions) + 0002 analytics

Web profile (Astro SSR): cardclaws.com/[handle] hero + flip, contact actions,
client-built vCard, visit attribution. Verified end-to-end.

Mobile (Expo SDK 51): auth, card list/create, builder v1 (bg/text/logo,
palette, undo/redo), Skia/Reanimated viewer (flip + ambient). 22 logic tests.

CI: policy/backend/profile/mobile jobs; LOC + no-placeholder lint.

Review fixes baked in: `back` (not `cardclaws`) key; strip image is a bundled
manifest file (not a URL); sessions table added; NFC reframed; test doubles
allowed for external services.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-04 10:17:26 -05:00