Privacy Policy
This page describes how Plink (the "service") collects, uses, and protects user data. The same policy is also available inside the app at Settings → Legal → Privacy Policy. Both copies must stay in sync on every amendment.
1. Data we collect
At sign-up
- Email address (required, verified)
- Password (one-way hashed via Supabase Auth)
Profile (optional)
- Name, nickname
- Birth date
- Gender
Using the service
- Couple link (invite code, anniversary date)
- Calendar events, todos, anniversaries, photos (base64 during beta)
- Device push tokens
- AI reminder responses (per-user, partner-blind)
External integrations
- Google Calendar OAuth access, refresh tokens
- Google Calendar events within sync scope
Payments (Store)
- Apple, Google in-app purchase receipts
- RevenueCat purchase ID (receipt-fraud protection)
- Coin balance and transaction ledger
2. Why we collect it
| Purpose | Data used |
|---|---|
| Authentication | Email, password hash |
| Core features (calendar, todos, D-Day) | Profile, couple, schedule |
| AI recommendations | See §4 for the exact field list per function |
| Push notifications | Device push token |
| Google Calendar sync | OAuth tokens, calendar events |
| Coins, payments | IAP receipts, transaction ledger |
3. Couple-shared data
Plink is built for two people who share data.
Togetherevents, todos, anniversaries: visible to both partners (read, write, delete).Mineevents, todos: visible only to the creator (enforced by Row-Level Security on theaudiencecolumn).Partnerevents: items created for the partner to see. Visible to both.- Profile (name, birth, gender): exposed only to the partner via
partner_public_view. - Photos (base64): inherit the audience of their parent event or anniversary.
- AI reminder responses: caller only (per-user
reminder_states, partner-blind). - Gift wishlist: observer-only. Recipients cannot see lists made for them (surprise protection).
When one partner deletes their account, items they created remain with their creator_id preserved. The couple itself is soft-deleted (deleted_at = NOW()). The partner cannot re-link via an old invite code (Migration 036).
4. AI features: what we send to OpenAI (full disclosure)
Plink uses OpenAI's gpt-4o-mini model in five places. Each one sends only the fields listed.
4-1. D-7 recommendation (generate-recommendation)
Sent: anniversary type, years, days, your D-14 answer (yes, no), tone, locale
Not sent: any name, email, photo, memo, location, or other events, todos
4-2. D-Day message (generate-dday-message)
Sent: anniversary type, years, days, your nickname, partner's nickname, birthday-owner flag, tone, locale
Not sent: email, photo, memo, location, other events, todos
Why both nicknames: the two partners receive different messages that reference the other by name. Nicknames are capped at 32 characters.
4-3. Daily comment (generate-daily-comment)
Sent: your nickname, partner's nickname (when set), dating days, today's date, tone, locale
Not sent: email, photo, memo, location, other events, todos
4-4. Gift recommendation (ai-gift-recommend, Store)
Sent: partner profile you entered (nickname, interests, tags. Only when you tap the button), anniversary type, budget
Not sent: any email, photo, memo, location
Why partner profile: the recommendation is for your partner, called only when you explicitly tap "Get AI suggestions" in the Store. 32-character caps.
4-5. Date course plan (ai-course-plan, Store)
Sent: location, date, preferences, budget
Not sent: any name, email, photo, memo
Caching
- D-7 recommendation: cached 7 days in
ai_response_cache - D-Day message: cached forever, per user, in
dday_messages(so the same anniversary keeps the same wording. Emotional continuity) - Gift, course: not cached (generated on every tap)
- OpenAI's own retention follows their API data usage policy (not used for training, deleted after 30-day abuse monitoring)
Rate limit
- 10 calls, minute and 50, day per user per function (atomic advisory-lock RPC)
- All five AI surfaces share this cap structure
Opt-out
- This beta does not yet have a global toggle (planned for launch as Settings → AI off)
- Workarounds: set individual anniversaries to
reminder_enabled = false; don't tap the Store AI buttons (they are explicit opt-in)
5. Third-party processors
| Service | Region | Data | Purpose |
|---|---|---|---|
| Supabase | US (AWS us-east-1) | All data | Database, auth, realtime |
| OpenAI | US | Only the fields listed in §4 | AI message generation |
| US | OAuth tokens, calendar events | Two-way Google Calendar sync | |
| Apple | US | Push tokens | iOS push notifications |
| Google FCM | US | Push tokens | Android push notifications |
| RevenueCat | US | IAP receipts, user_id | Receipt verification |
| Cloudflare | US | Web traffic (beta) | Static site hosting |
6. Retention
- Active account: for the duration of service use
- Account deletion: permanent, immediate
auth.admin.deleteUser→auth.userscascade removes profile, settings, events, todos, anniversaries- Couple is soft-deleted (
couples.deleted_at = NOW()). The partner cannot resurrect with an old invite code (Migration 036)
- Legal retention (e.g. Korean Electronic Commerce Act): the statutory minimum (payment records: 5 years)
7. Your rights
| Right | How to exercise |
|---|---|
| Access | Profile screen in the app |
| Rectify | Profile, Settings in the app |
| Delete | Settings → Delete Account (immediate cascade) |
| Withdraw consent, object | Contact below (§9) |
| Data portability | Email request (CSV, JSON export, handled manually during beta) |
8. Security
- All transport over HTTPS, TLS 1.3
- Supabase Row-Level Security applied to every table
- One-way password hashing (Supabase Auth, PBKDF2-HMAC)
- OAuth tokens stored in
user_connections(RLS: owner only) - AI call rate limit (10, min · 50, day, atomic advisory-lock RPC)
- Coin spending guarded by caller-match (Migration 035)
- Soft-deleted couples cannot be rejoined (Migration 036)
9. Data protection contact
- Name: Chanjoong Kim
- Email: plink.calendar@gmail.com
10. Cookies and local storage
The web build at plink-web-cg0.pages.dev uses:
localStorage: Supabase auth session (required to use the service)- Mobile app:
AsyncStorage,expo-secure-store(same purpose)
No advertising or tracking cookies.
11. Minors
Sign-up is not permitted for users under 14.
12. Change notice
This policy may be amended. Material changes will be announced in-app or by email. Frequent changes are expected during beta.