diff --git a/ClaudeQACoverage.md b/ClaudeQACoverage.md index 12e9adaa..43a8e8e5 100644 --- a/ClaudeQACoverage.md +++ b/ClaudeQACoverage.md @@ -33,7 +33,7 @@ | K — Billing & subscription lifecycle | Gate (couple-shared unlock) verified via admin toggle (Pass A) + Premium-unlock modal + `onEntitlementChanged` push live (R13/R14). **Real money path (purchase/restore/cancel→expiry-relock/refund/plan-switch) NOT tested** — needs a real device + Play sandbox. | ⚠️ **todo** — money path `blocked→needs-device`; gate ✅ | | L — Messaging & chat (E2E) | R15: conversation render driven live — decrypt **both dirs**, attribution, timestamps, **Seen** receipt, ❤️ **reaction**, ordering, day-separators, voice-note + image bubbles, E2E composer lock glyphs; inbox decrypted previews **no `enc:` leak**; live QA→Sam send delivered; at-rest `enc:v1:`. **R18 re-verified live round-trip** (Sam→QA: received + decrypted on partner, `enc:v1:`(79) at rest, marker absent from server docs = no leak, Seen receipt). Remaining: failed-send/offline retry, delete-message, fresh image/voice send, Discuss-thread live send. | ✅ **pass (core)** — re-confirmed R18; 4 sub-items carry | | M — Settings & account management | R15: **M-001 (quiet hours) FIXED + verified live** (server-side fail-open suppression); per-type notif toggle take-effect confirmed live (server-enforced; field flips in Firestore; toggle-off → 0 delivery); theme/DataStore persistence across relaunch ✅; biometric lock code-sound (cold-start re-lock; background-resume observation → Future.md). Remaining: edit-profile persist, unpair/delete-cascade (disruptive — deferred). **R18: M-001 re-confirmed** — toggling QH writes the client mirror (`quietHoursEnabled`/`StartMinutes 1320`/`EndMinutes 480`/`timezone`) to `users/{uid}` correctly; server suppression deployed + R15-verified. Recommend prune. | ✅ **pass (core)** — M-001 confirmed (prune next); unpair/delete deferred | -| N — Daily Q / reveal / check-ins / interactive | R15 (driven): daily-Q + **reveal both-answered gate** ✓; **Bucket List CRUD FIXED+verified (N-001)** — add(`enc:v1:`)/complete/delete/list; **Date Builder FIXED+verified (N-002)** — Create Plan → PLANNED `date_plan` (`enc:v1:`) → Home "Date coming up"; Outcomes/Your Progress code-correct (resolves coupleId, submits); Activity feed render-checked (prior). | ✅ **pass** — N-001 + N-002 fixed (pending 1 confirm) | +| N — Daily Q / reveal / check-ins / interactive | R15 (driven): daily-Q + **reveal both-answered gate** ✓; **Bucket List CRUD FIXED+verified (N-001)** — add(`enc:v1:`)/complete/delete/list; **Date Builder FIXED+verified (N-002)** — Create Plan → PLANNED `date_plan` (`enc:v1:`) → Home "Date coming up"; Outcomes/Your Progress code-correct (resolves coupleId, submits); Activity feed render-checked (prior). **R25: NEW Date Memories/Reflection feature landed (reverted-then-reinstated → slipped prior rounds); fixed 5 escaped bugs — DR-TYPING (imePadding), DR-DEEPLINK-BG (MainActivity dropped date_id), DR-FEED-ROUTE (Together `date`→DATE_MATCHES), DR-LOADER (DateMemories infinite spinner on read error), DR-LOCKED (blank dashes when vault locked); + notes field, edit-before-reveal, opened-push. NEEDS live QA pass (both devices, bg+fg notifications).** | ⚠️ **partial** — N-001/N-002 fixed; **Date Memories/Reflection = todo (new R25, needs 2-device live run)** | | O — Release build & store readiness | **Not started.** All QA to date is on the **debug** APK. Minified release build, signing/AAB, App Check enforcement, i18n/RTL, App-Links, Play Data-Safety = pre-ship gate, not yet run. | ❌ **todo (pre-ship gate)** | | P — Content, copy & language | R15: UI-microcopy swept (warm/inclusive; debug rows `BuildConfig.DEBUG`-gated; friendly error fallbacks; on-brand privacy copy) + **question-bank audit live: 6103 Qs — 0 empty, 0 exact dupes, 0 placeholder tokens, complete/mutually-exclusive answer configs, good type variety, consent-framed sensitive content.** No typos/off-voice/non-inclusive copy found. **R18: found+fixed P-GRAMMAR-001** — in-game wheel surfaced a subject-verb agreement error; bank scan found **13 stress-Q** from one template family where plural subjects hit a singular "{x} is …" frame ("busy weeks/health worries/… is affecting you"); fixed the 13 rows in asset `app.db` (data-only); root fix belongs in the content generator. | ✅ **pass** — copy clean; P-GRAMMAR-001 fixed (asset) + grammar-audit recommended | diff --git a/ClaudeQAPlan.md b/ClaudeQAPlan.md index 120e0d95..5254d7fc 100644 --- a/ClaudeQAPlan.md +++ b/ClaudeQAPlan.md @@ -308,6 +308,11 @@ surface and reconcile it with `ClaudeQACoverage.md`: remote config, and any debug-only screens that should not ship. - **Backend/rules:** inspect Firestore rules, indexes/queries, Functions triggers/callables, Storage paths, scheduled jobs, and migrations for new data shapes or access paths. +- **⛔ Reverted-then-reinstated code (this is exactly how Date Memories/Reflection slipped R25):** diff the working + tree against the coverage matrix — `git status --short` staged **additions** (`A `) and the recent `git log` for + `Revert`/`re-add` churn. A feature that was reverted and later re-added is **new to QA even if the commits look old**; + re-enter it into the relevant passes. Cross-check that every `AppRoute`/notification type/Function trigger present in + code has a coverage row. - **Docs update rule:** if the inventory finds a page, feature, notification, asset, state, backend path, or edge case missing from the playbook/coverage, update `ClaudeQAPlan.md` and `ClaudeQACoverage.md` before marking the chunk done. - **Scanner update rule:** if a manual finding is a pattern an existing scanner *should* have caught (e.g. a hardcoded @@ -724,8 +729,14 @@ Account); Paywall; Your Progress/Activity; Recovery. - **D1 At-rest coverage:** admin-read RAW docs/objects, assert ciphertext for every private type — chat text + `lastMessagePreview` (`enc:v1:`), chat media bytes (Tink `01 69 59 51 f0…`), answers (`sealed:v1:`/`enc:v1:`), - date plans + `date_swipes`, Memory Lane capsules, Bucket List. Also: **wrappedCoupleKey** + recovery material never + date plans + `date_swipes`, **date reflections** (`date_reflections/{dateId}/answers/{uid}/secure/payload` = + `enc:v1:`; the `date_history` metadata doc is intentionally plaintext title/category/timestamp — no private words), + Memory Lane capsules, Bucket List. Also: **wrappedCoupleKey** + recovery material never plaintext; **invite code (KDF seed) never stored raw**; **no push payload carries private content**. + - **Date-reflection "private until both" gate + edit-seal (R25):** before you reflect, a D3 raw-API read of your + partner's `secure/payload` must be **denied**; after you reflect, it's allowed. And the author's edit-before-reveal + (secure `update`) must be **denied once the partner has reflected** (the seal holds) — verify both live via the + raw-API angle, not just the UI. - **D2 Rules audit (static):** member-only reads, author/server-only writes, ciphertext enforced on every private field, immutability, **no premium self-grant**, entitlements write:false; re-audit conversations/typing/reactions + entitlement partner-read; **no catch-all** `match /{document=**}`; list/query not enumerable; `get()`-rules don't @@ -916,7 +927,13 @@ open**. No duplicates; rate limiter (20/day, 100/week) doesn't drop legit ones. in-app/Together record**; tapping the push → Home, not a dead-end) · `date_reflection_partner`/`date_reflection_ready`(**onDateReflectionWritten** → partner → the date reflection; "your turn" when one reflects, "ready to reveal" when both; gated `notifPartnerAnswered`+quiet hours) · + `date_reflection_opened`(**onDateReflectionRevealed** → partner → "opened your reflection", after both reveal) · `date_logged`(**onDateHistoryCreated** → partner → reflect on the just-logged date) · +   ⚠️ **date deep-link regression guard (R25 — Changes 2 & 3):** for every `date_*` type, tapping must + open the **exact date's reflection** in **BOTH background (OS tray) and foreground** — background nearly broke + because `MainActivity` dropped `date_id` from the payload (fell back to DATE_MEMORIES); and the in-app + **Together-feed** row for these types must route to **DATE_MEMORIES**, not DATE_MATCHES (the old + `"date" in type` substring bug). Test the feed row AND the OS notification, not just one. · `restore_requested`(**onRestoreRequested** → partner → the restore-consent screen; high-signal help request, NOT suppressed by the routine partner-activity toggle, only quiet hours) · `spki`(key identity/confirm → security/key screen) · `subscription_entitlement_changed` & `security_recovery` (if present). @@ -1053,7 +1070,9 @@ reads, missing cache use, and slow navigation. Drive each route as a user and in frame, and `Choreographer: Skipped N frames` / main-thread stalls in logcat. Transitions/animations stay smooth (~60fps). - **Redundant Firestore / network reads:** count listeners/gets per screen. Switching bottom tabs and returning must **not** refetch unchanged data; opening a screen twice must not double-read; **snapshot listeners detach on leave** - (no leaked/stacked listeners — a 2-user realtime app accumulates these fast). Watch for N+1 reads on lists. + (no leaked/stacked listeners — a 2-user realtime app accumulates these fast). Watch for N+1 reads on lists — + e.g. **DateMemories** derives each row's reflection state with per-row `hasReflected` gets; confirm they're + cached per `dateId` and not re-fetched for every history-snapshot tick (R25 improvement). - **Memory leaks (beyond listener leaks):** add **LeakCanary** in the debug build (or take heap dumps) and navigate in→out of every heavy screen (conversation with media, game, image viewer, Memory Lane) repeatedly — flag retained Activities/Composables/bitmaps/Contexts. A leak that grows per navigation = bug (P2; **P1** if it OOMs). @@ -1075,6 +1094,14 @@ reads, missing cache use, and slow navigation. Drive each route as a user and in Every **primary flow** must be usable with accessibility settings on. Enable each setting and walk the core flows (auth, onboarding, pairing, Home, a full game, daily question + reveal, Messages, Paywall, Settings) end to end. This is the deep home for a11y; the Pass C contrast/font spot-checks feed into it. +- **⛔ Keyboard / IME overlap (run `scripts/ime-scan.sh` FIRST — it must PASS):** the app is edge-to-edge + (`adjustResize` doesn't resize the window), so a text-input screen missing `imePadding()`/`safeDrawingPadding()` + lets the soft keyboard **cover the fields** — the exact "you can't type in Date Reflection" bug (R25). The + scanner flags any text-input file lacking IME handling (allowlisting components whose host handles it); a + MISSING hit is a bug. Then **live-verify per input screen**: focus each field with the keyboard open and + confirm the focused field stays visible and typable (don't assume — the daily flow is choice-only, so it + never exercises this). Input screens: auth (login/signup/forgot), onboarding/profile, pairing/invite/recovery, + Messages conversation, Bucket List, Date Builder, **Date Reflection**, Change/Delete/Edit in Settings, Wheel. - **Font scaling:** `adb shell settings put system font_scale 1.3` (then 1.5, 2.0) — every primary flow stays usable: **no clipped/overlapping text, no cut-off or hidden buttons/actions** (scroll where needed). **Acceptance: all primary flows usable at increased font scale without clipped buttons or hidden actions.** Restore `font_scale 1.0` after. @@ -1232,6 +1259,16 @@ defect class — audit that each EXISTS: The non-game interactive surfaces that have no functional home (Pass B is games only). Read [Daily question lifecycle](docs/Engineering_Reference_Manual.md#daily-question-lifecycle). +- **Date Memories / Reflection (NEW — added R25; reverted-then-reinstated, so it slipped earlier rounds):** + log a date (Date Match → mark done → `date_history` row) → Home "Reflect on your date" nudge (fires for + **any** recent un-reflected date, not just the latest) → DateMemories timeline → tap a date → + DateReflectionScreen. Drive the full loop on **both** devices: type all **4** fields (favorite / surprised / + appreciated / free-form notes) — **confirm the keyboard does not cover the fields (Pass J / ime-scan)** — + save → AWAITING_PARTNER (with **Edit** affordance: edits allowed only until the partner reflects) → partner + reflects → both flip to the side-by-side REVEAL. Negative/edge: neither can read the other early (Pass D + gate); a **blank/deep-linked bad `dateId`** shows an error, not a malformed write; a **locked vault** + (key unavailable) shows "Locked", not blank dashes; DateMemories **read failure** shows an error state + (not an infinite spinner); long-press a memory → **Remove** (confirm) deletes it. Notifications in Pass E. - **Daily-question loop (the core daily ritual):** assignment (6 PM CST, `assignDailyQuestion`) → answer (each answer type) → **both-answered gate** (neither sees the other's answer until both submit) → **mutual reveal** → per-question **Discuss** thread (Pass L) → **Answer History** → **streak** increment + milestone celebration (`streak_milestone`) diff --git a/UI_UPGRADE.md b/UI_UPGRADE.md new file mode 100644 index 00000000..8bb334d4 --- /dev/null +++ b/UI_UPGRADE.md @@ -0,0 +1,120 @@ +# Closer UI Upgrade + +This document is the focused visual upgrade plan for making Closer feel more beautiful, polished, and emotionally specific without turning it into a decorative wellness app. + +The direction: keep the app calm and private, but make important relationship moments feel more intentional. + +## Upgrade Priorities + +### 1. Complete the Daily Question Visual Arc + +The Home screen should visually move through the daily question ritual. + +- `UNANSWERED`: use `illustration_tonight_partner_prompt` +- One partner answered: keep the answer-card ritual artwork +- `BOTH_ANSWERED`: use the new reveal-ready artwork +- `REVEALED`: use a calmer completed-state treatment, not the same urgency as reveal-ready + +Why this matters: + +The daily question is the core habit. The visuals should make the state obvious before the user reads the copy. + +### 2. Add Subtle Motion to High-Emotion States + +Use small, restrained motion only where it adds emotional clarity. + +Best targets: + +- A soft glow or pulse on the reveal-ready Home card +- Gentle fade/scale when a daily state changes +- A quiet success transition after both answers are revealed + +Avoid: + +- Constant decorative animation +- Bouncy motion +- Motion on dense settings, security, or history screens + +Why this matters: + +The app should feel alive, but still intimate and trustworthy. + +### 3. Polish the Home Screen Hierarchy + +The Home screen should make the next shared action unmistakable. + +Improve: + +- Give the primary card stronger visual priority than secondary cards +- Reduce competing surfaces around the daily question +- Make the primary CTA feel more tactile +- Keep secondary actions quieter and easier to scan + +Why this matters: + +Home should answer one question immediately: what should we do together next? + +### 4. Make Light Theme Feel Equally Designed + +Dark mode currently carries more of the mood. Light mode should feel intentional too. + +Improve: + +- Softer warm backgrounds +- Better contrast between cards and page surfaces +- Less clinical white space +- Light-mode versions of major illustrations where needed + +Why this matters: + +The product should feel premium in both themes, not like dark mode is the real design and light mode is the fallback. + +### 5. Create a More Satisfying Revealed State + +After both partners reveal answers, the app should not just feel "done." It should invite the next tiny moment of connection. + +Improve: + +- Add a softer post-reveal visual state +- Surface the follow-up prompt more beautifully +- Make saved reflections feel like a shared memory, not a log entry + +Why this matters: + +The reveal is not the end of the interaction. It is the beginning of the conversation. + +### 6. Keep the Illustration System Strict + +Illustrations should stay purposeful and surface-specific. + +Rules: + +- Do not reuse the same couple image everywhere +- Do not add characters to every screen +- Do not add large illustrations to privacy, security, account, or settings screens +- Use artwork for emotional transitions, empty states, and onboarding moments +- Keep dense task screens focused on content + +Why this matters: + +The app becomes more beautiful by being more intentional, not by adding more decoration. + +## First Implementation Batch + +Start with the smallest set of upgrades that visibly improves the app. + +1. Wire the daily question artwork states on Home. +2. Add the reveal-ready illustration for `BOTH_ANSWERED`. +3. Add a restrained visual emphasis to the reveal-ready CTA. +4. Review Home in dark and light mode. +5. Capture updated README screenshots after the states are stable. + +## Quality Bar + +An upgrade is successful if: + +- The screen feels calmer and more premium. +- The next action is clearer. +- The emotional state is obvious before reading every word. +- The app still feels private and serious. +- No screen becomes busier just because new artwork exists. diff --git a/app/src/main/java/app/closer/MainActivity.kt b/app/src/main/java/app/closer/MainActivity.kt index e841e7cf..946960d3 100644 --- a/app/src/main/java/app/closer/MainActivity.kt +++ b/app/src/main/java/app/closer/MainActivity.kt @@ -224,6 +224,7 @@ class MainActivity : AppCompatActivity() { gameType = intent.getStringExtra("game_type"), capsuleId = intent.getStringExtra("capsule_id"), challengeId = intent.getStringExtra("challenge_id"), + dateId = intent.getStringExtra("date_id"), avatarUrl = intent.getStringExtra("sender_avatar_url") ) return PartnerNotificationType.fromRemoteType(type)?.routeFor(payload, coupleId) diff --git a/app/src/main/java/app/closer/data/remote/FirestoreDateReflectionDataSource.kt b/app/src/main/java/app/closer/data/remote/FirestoreDateReflectionDataSource.kt index 85ee8208..5ed18332 100644 --- a/app/src/main/java/app/closer/data/remote/FirestoreDateReflectionDataSource.kt +++ b/app/src/main/java/app/closer/data/remote/FirestoreDateReflectionDataSource.kt @@ -33,27 +33,48 @@ class FirestoreDateReflectionDataSource @Inject constructor( private fun securePayloadRef(coupleId: String, dateId: String, userId: String) = answerRef(coupleId, dateId, userId).collection("secure").document("payload") - /** Save my reflection: encrypted content in the gated secure subdoc + a content-free metadata doc. */ + /** + * Save my reflection: encrypted content in the gated secure subdoc + a content-free metadata doc. + * Both docs are committed in a single [com.google.firebase.firestore.WriteBatch] so a mid-write + * failure can't leave an orphaned payload without its metadata (which is what gates reads/state). + */ suspend fun saveReflection(coupleId: String, dateId: String, userId: String, reflection: DateReflection) { val aead = encryptionManager.aeadFor(coupleId) ?: throw IllegalStateException("Couple key unavailable for $coupleId") val payload = fieldEncryptor.encrypt(encode(reflection), aead, coupleId) val now = System.currentTimeMillis() + val batch = db.batch() + batch.set(securePayloadRef(coupleId, dateId, userId), mapOf("encryptedPayload" to payload)) + batch.set( + answerRef(coupleId, dateId, userId), + mapOf( + "userId" to userId, + "schemaVersion" to DateReflection.SCHEMA_VERSION, + "createdAt" to now, + "updatedAt" to now, + "isRevealed" to false + ) + ) + suspendCancellableCoroutine { cont -> + batch.commit() + .addOnSuccessListener { cont.resume(Unit) } + .addOnFailureListener { cont.resumeWithException(it) } + } + } + + /** + * Overwrite my own still-sealed reflection content (edit-before-reveal). Only the encrypted payload is + * rewritten (metadata/`createdAt` preserved). The Firestore rule permits this only while my partner + * has NOT yet reflected — once they have, the content is immutable (the seal holds). + */ + suspend fun updateReflection(coupleId: String, dateId: String, userId: String, reflection: DateReflection) { + val aead = encryptionManager.aeadFor(coupleId) + ?: throw IllegalStateException("Couple key unavailable for $coupleId") + val payload = fieldEncryptor.encrypt(encode(reflection), aead, coupleId) suspendCancellableCoroutine { cont -> securePayloadRef(coupleId, dateId, userId).set(mapOf("encryptedPayload" to payload)) .addOnSuccessListener { cont.resume(Unit) }.addOnFailureListener { cont.resumeWithException(it) } } - suspendCancellableCoroutine { cont -> - answerRef(coupleId, dateId, userId).set( - mapOf( - "userId" to userId, - "schemaVersion" to DateReflection.SCHEMA_VERSION, - "createdAt" to now, - "updatedAt" to now, - "isRevealed" to false - ) - ).addOnSuccessListener { cont.resume(Unit) }.addOnFailureListener { cont.resumeWithException(it) } - } } /** True once a user has reflected (metadata doc readable by both → drives the "your turn" state). */ @@ -95,6 +116,7 @@ class FirestoreDateReflectionDataSource @Inject constructor( favoriteMoment = o.optString("favoriteMoment"), surprise = o.optString("surprise"), appreciated = o.optString("appreciated"), + notes = o.optString("notes"), isRevealed = true, schemaVersion = o.optInt("schemaVersion", DateReflection.SCHEMA_VERSION) ) @@ -113,6 +135,7 @@ class FirestoreDateReflectionDataSource @Inject constructor( put("favoriteMoment", r.favoriteMoment) put("surprise", r.surprise) put("appreciated", r.appreciated) + put("notes", r.notes) put("schemaVersion", DateReflection.SCHEMA_VERSION) }.toString() } diff --git a/app/src/main/java/app/closer/domain/model/DateReflection.kt b/app/src/main/java/app/closer/domain/model/DateReflection.kt index 9df63a1d..46ecdb2c 100644 --- a/app/src/main/java/app/closer/domain/model/DateReflection.kt +++ b/app/src/main/java/app/closer/domain/model/DateReflection.kt @@ -1,9 +1,10 @@ package app.closer.domain.model /** - * A partner's private post-date reflection (3 prompts). The content is couple-key encrypted and lives in - * a read-gated `secure/payload` subdoc — neither partner can read the other's until BOTH have reflected - * (enforced by the Firestore rule, mirroring the daily-question reveal). Privacy-native by design. + * A partner's private post-date reflection (3 fixed prompts + an optional free-form note). The content is + * couple-key encrypted and lives in a read-gated `secure/payload` subdoc — neither partner can read the + * other's until BOTH have reflected (enforced by the Firestore rule, mirroring the daily-question reveal). + * Privacy-native by design. */ data class DateReflection( val dateId: String = "", @@ -11,15 +12,17 @@ data class DateReflection( val favoriteMoment: String = "", val surprise: String = "", val appreciated: String = "", + val notes: String = "", val isRevealed: Boolean = false, val createdAt: Long = 0L, val schemaVersion: Int = SCHEMA_VERSION ) { val isEmpty: Boolean - get() = favoriteMoment.isBlank() && surprise.isBlank() && appreciated.isBlank() + get() = favoriteMoment.isBlank() && surprise.isBlank() && appreciated.isBlank() && notes.isBlank() companion object { - const val SCHEMA_VERSION = 1 + // v2 adds the optional free-form `notes` field (additive; older docs decode with notes = ""). + const val SCHEMA_VERSION = 2 } } diff --git a/app/src/main/java/app/closer/notifications/PartnerNotificationManager.kt b/app/src/main/java/app/closer/notifications/PartnerNotificationManager.kt index cc97d9f5..b1989e39 100644 --- a/app/src/main/java/app/closer/notifications/PartnerNotificationManager.kt +++ b/app/src/main/java/app/closer/notifications/PartnerNotificationManager.kt @@ -260,6 +260,12 @@ enum class PartnerNotificationType( channelId = NotificationChannelSetup.CHANNEL_PARTNER_ACTIONS, rateType = NotificationRateLimiter.Type.PARTNER_TRIGGER ), + DATE_REFLECTION_OPENED( + title = "Your partner opened your reflection ✨", + body = "Open to see what you each wrote.", + channelId = NotificationChannelSetup.CHANNEL_PARTNER_ACTIONS, + rateType = NotificationRateLimiter.Type.PARTNER_TRIGGER + ), // Partner-assisted restore: the partner is locked out on a new device and needs your help to // restore their history. High-signal help request — not suppressed by routine activity toggles. RESTORE_REQUESTED( @@ -352,7 +358,7 @@ enum class PartnerNotificationType( CAPSULE_UNLOCKED -> AppRoute.MEMORY_LANE GENTLE_REMINDER -> AppRoute.DAILY_QUESTION THINKING_OF_YOU -> AppRoute.HOME - DATE_REFLECTION_PARTNER, DATE_REFLECTION_READY, DATE_LOGGED -> + DATE_REFLECTION_PARTNER, DATE_REFLECTION_READY, DATE_LOGGED, DATE_REFLECTION_OPENED -> payload.dateId?.let { AppRoute.dateReflection(it) } ?: AppRoute.DATE_MEMORIES RESTORE_REQUESTED -> AppRoute.RESTORE_CONSENT // Tapping the "was this you?" alert opens account security so the owner can react. @@ -391,6 +397,7 @@ enum class PartnerNotificationType( "thinking_of_you" -> THINKING_OF_YOU "date_reflection_partner" -> DATE_REFLECTION_PARTNER "date_reflection_ready" -> DATE_REFLECTION_READY + "date_reflection_opened" -> DATE_REFLECTION_OPENED "date_logged" -> DATE_LOGGED "restore_requested" -> RESTORE_REQUESTED "restore_self_alert" -> RESTORE_SELF_ALERT diff --git a/app/src/main/java/app/closer/ui/activity/ActivityScreen.kt b/app/src/main/java/app/closer/ui/activity/ActivityScreen.kt index b1d55e13..80e3102c 100644 --- a/app/src/main/java/app/closer/ui/activity/ActivityScreen.kt +++ b/app/src/main/java/app/closer/ui/activity/ActivityScreen.kt @@ -121,6 +121,9 @@ private fun routeForActivityType(type: String): String? { "game" in t -> AppRoute.PLAY "capsule" in t -> AppRoute.MEMORY_LANE "challenge" in t -> AppRoute.CONNECTION_CHALLENGES + // Reflection / logged-date activity → the Replay timeline (the feed row has no dateId; the user + // taps the specific date there). Must precede the generic "date" → matches rule below. + "reflection" in t || t == "date_logged" -> AppRoute.DATE_MEMORIES "date" in t -> AppRoute.DATE_MATCHES "answer" in t || "reveal" in t || "question" in t || "daily" in t -> AppRoute.DAILY_QUESTION else -> null diff --git a/app/src/main/java/app/closer/ui/dates/DateMemoriesScreen.kt b/app/src/main/java/app/closer/ui/dates/DateMemoriesScreen.kt index 6d8503ba..13f3fc5e 100644 --- a/app/src/main/java/app/closer/ui/dates/DateMemoriesScreen.kt +++ b/app/src/main/java/app/closer/ui/dates/DateMemoriesScreen.kt @@ -1,6 +1,7 @@ package app.closer.ui.dates -import androidx.compose.foundation.clickable +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -12,12 +13,17 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.AlertDialog import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight @@ -27,6 +33,7 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.closer.R +import app.closer.core.crash.CrashReporter import app.closer.core.navigation.AppRoute import app.closer.data.remote.FirestoreDateMemoryDataSource import app.closer.data.remote.FirestoreDateReflectionDataSource @@ -44,6 +51,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import java.text.DateFormat @@ -54,7 +62,8 @@ data class DateMemoryRow(val memory: DateMemory, val state: DateReflectionState) data class DateMemoriesUiState( val isLoading: Boolean = true, - val rows: List = emptyList() + val rows: List = emptyList(), + val error: String? = null ) @HiltViewModel @@ -62,12 +71,18 @@ class DateMemoriesViewModel @Inject constructor( private val memoryDataSource: FirestoreDateMemoryDataSource, private val reflectionDataSource: FirestoreDateReflectionDataSource, private val authRepository: AuthRepository, - private val coupleRepository: CoupleRepository + private val coupleRepository: CoupleRepository, + private val crashReporter: CrashReporter ) : ViewModel() { private val _uiState = MutableStateFlow(DateMemoriesUiState()) val uiState: StateFlow = _uiState.asStateFlow() + private var coupleId: String? = null + // Cache reflection-state per dateId so a history re-emit only fetches state for newly-seen dates + // (avoids O(2N) reads on every tick). + private val reflectionStateCache = mutableMapOf() + init { viewModelScope.launch { val uid = authRepository.currentUserId @@ -76,22 +91,42 @@ class DateMemoriesViewModel @Inject constructor( _uiState.update { it.copy(isLoading = false) } return@launch } + coupleId = couple.id val partnerId = couple.userIds.firstOrNull { it != uid } - memoryDataSource.observeHistory(couple.id).collect { memories -> - val rows = memories.map { m -> - val mine = runCatching { reflectionDataSource.hasReflected(couple.id, m.id, uid) }.getOrDefault(false) - val partner = partnerId?.let { - runCatching { reflectionDataSource.hasReflected(couple.id, m.id, it) }.getOrDefault(false) - } ?: false - val state = when { - mine && partner -> DateReflectionState.BOTH_DONE - mine -> DateReflectionState.AWAITING_PARTNER - else -> DateReflectionState.NONE - } - DateMemoryRow(m, state) + memoryDataSource.observeHistory(couple.id) + .catch { e -> + crashReporter.recordException(e) + _uiState.update { it.copy(isLoading = false, error = "Couldn't load your dates. Check your connection and try again.") } } - _uiState.update { it.copy(isLoading = false, rows = rows) } - } + .collect { memories -> + val rows = memories.map { m -> + val state = reflectionStateCache[m.id] ?: run { + val mine = runCatching { reflectionDataSource.hasReflected(couple.id, m.id, uid) }.getOrDefault(false) + val partner = partnerId?.let { + runCatching { reflectionDataSource.hasReflected(couple.id, m.id, it) }.getOrDefault(false) + } ?: false + val s = when { + mine && partner -> DateReflectionState.BOTH_DONE + mine -> DateReflectionState.AWAITING_PARTNER + else -> DateReflectionState.NONE + } + reflectionStateCache[m.id] = s + s + } + DateMemoryRow(m, state) + } + _uiState.update { it.copy(isLoading = false, error = null, rows = rows) } + } + } + } + + fun deleteMemory(id: String) { + val cid = coupleId ?: return + reflectionStateCache.remove(id) + viewModelScope.launch { + runCatching { memoryDataSource.delete(cid, id) } + .onFailure { crashReporter.recordException(it) } + // observeHistory re-emits without the row; no manual state edit needed. } } } @@ -102,25 +137,57 @@ fun DateMemoriesScreen( viewModel: DateMemoriesViewModel = hiltViewModel() ) { val state by viewModel.uiState.collectAsState() + var pendingDelete by remember { mutableStateOf(null) } + SettingsSubpage(title = "Date memories", onBack = { onNavigate("back") }) { padding -> when { state.isLoading -> Box(Modifier.fillMaxSize().padding(padding), Alignment.Center) { CloserHeartLoader() } + state.error != null -> Box(Modifier.fillMaxSize().padding(padding).padding(horizontal = 24.dp), Alignment.Center) { + Text( + state.error!!, + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurfaceVariant, + textAlign = TextAlign.Center + ) + } state.rows.isEmpty() -> DateMemoriesEmpty(Modifier.padding(padding)) else -> LazyColumn( modifier = Modifier.fillMaxSize().padding(padding).padding(horizontal = 20.dp), verticalArrangement = Arrangement.spacedBy(12.dp) ) { items(state.rows, key = { it.memory.id }) { row -> - DateMemoryCard(row) { onNavigate(AppRoute.dateReflection(row.memory.id)) } + DateMemoryCard( + row = row, + onClick = { onNavigate(AppRoute.dateReflection(row.memory.id)) }, + onLongClick = { pendingDelete = row.memory } + ) } } } } + + pendingDelete?.let { memory -> + AlertDialog( + onDismissRequest = { pendingDelete = null }, + title = { Text("Remove this date?") }, + text = { Text("This removes \"${memory.title.ifBlank { "this date" }}\" from your timeline. Your reflections won't be shown.") }, + confirmButton = { + TextButton(onClick = { viewModel.deleteMemory(memory.id); pendingDelete = null }) { + Text("Remove", color = MaterialTheme.colorScheme.error) + } + }, + dismissButton = { TextButton(onClick = { pendingDelete = null }) { Text("Cancel") } } + ) + } } +@OptIn(ExperimentalFoundationApi::class) @Composable -private fun DateMemoryCard(row: DateMemoryRow, onClick: () -> Unit) { - CloserCard(modifier = Modifier.fillMaxWidth().clickable(onClick = onClick), containerColor = closerCardColor()) { +private fun DateMemoryCard(row: DateMemoryRow, onClick: () -> Unit, onLongClick: () -> Unit) { + CloserCard( + modifier = Modifier.fillMaxWidth().combinedClickable(onClick = onClick, onLongClick = onLongClick), + containerColor = closerCardColor() + ) { Row( modifier = Modifier.fillMaxWidth().padding(16.dp), horizontalArrangement = Arrangement.spacedBy(12.dp), diff --git a/app/src/main/java/app/closer/ui/dates/DateReflectionScreen.kt b/app/src/main/java/app/closer/ui/dates/DateReflectionScreen.kt index aaf82533..8a6069a3 100644 --- a/app/src/main/java/app/closer/ui/dates/DateReflectionScreen.kt +++ b/app/src/main/java/app/closer/ui/dates/DateReflectionScreen.kt @@ -7,12 +7,14 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Button import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -21,12 +23,14 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.closer.core.crash.CrashReporter +import app.closer.data.remote.FirestoreDateMemoryDataSource import app.closer.data.remote.FirestoreDateReflectionDataSource import app.closer.domain.model.DateReflection import app.closer.domain.repository.AuthRepository @@ -44,30 +48,39 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import javax.inject.Inject -/** The three fixed post-date reflection prompts. */ +/** The four post-date reflection prompts (the last is an open-ended, optional note). */ private val REFLECTION_PROMPTS = listOf( "Your favorite moment", "What surprised you", - "What you appreciated most" + "What you appreciated most", + "Anything else worth remembering" ) -enum class ReflectionPhase { LOADING, EDIT, AWAITING_PARTNER, REVEALED, ERROR } +/** Max characters per reflection field — keeps the encrypted payload bounded. */ +private const val MAX_PROMPT_LEN = 500 +private const val MAX_NOTES_LEN = 1000 + +enum class ReflectionPhase { LOADING, EDIT, AWAITING_PARTNER, REVEALED, LOCKED, ERROR } data class DateReflectionUiState( val phase: ReflectionPhase = ReflectionPhase.LOADING, + val dateTitle: String? = null, val partnerName: String? = null, val favoriteMoment: String = "", val surprise: String = "", val appreciated: String = "", + val notes: String = "", val mine: DateReflection? = null, val partner: DateReflection? = null, val isSaving: Boolean = false, + val isEditing: Boolean = false, val error: String? = null ) @HiltViewModel class DateReflectionViewModel @Inject constructor( private val reflectionDataSource: FirestoreDateReflectionDataSource, + private val memoryDataSource: FirestoreDateMemoryDataSource, private val authRepository: AuthRepository, private val coupleRepository: CoupleRepository, private val userRepository: UserRepository, @@ -81,10 +94,16 @@ class DateReflectionViewModel @Inject constructor( private var coupleId: String? = null private var partnerId: String? = null + private var revealedMarked = false init { load() } private fun load() { + // Defensive: a missing/malformed nav arg would otherwise read/write an empty path segment. + if (dateId.isBlank()) { + _uiState.update { it.copy(phase = ReflectionPhase.ERROR, error = "This date couldn't be opened.") } + return + } viewModelScope.launch { val uid = authRepository.currentUserId val couple = uid?.let { runCatching { coupleRepository.getCoupleForUser(it) }.getOrNull() } @@ -97,7 +116,10 @@ class DateReflectionViewModel @Inject constructor( val partnerName = partnerId?.let { runCatching { userRepository.getUser(it)?.displayName }.getOrNull() }?.takeIf { it.isNotBlank() } ?: "your partner" - _uiState.update { it.copy(partnerName = partnerName) } + val dateTitle = runCatching { + memoryDataSource.getHistoryOnce(couple.id).firstOrNull { it.id == dateId }?.title + }.getOrNull()?.takeIf { it.isNotBlank() } + _uiState.update { it.copy(partnerName = partnerName, dateTitle = dateTitle) } refresh() // Live-complete the reveal the moment the partner reflects. partnerId?.let { pid -> @@ -129,15 +151,41 @@ class DateReflectionViewModel @Inject constructor( val partner = pid?.let { runCatching { reflectionDataSource.decryptReflectionFor(cid, dateId, it) }.getOrNull() } - runCatching { reflectionDataSource.markRevealed(cid, dateId, uid) } + // Both reflected but we can't decrypt (couple key unavailable on this device, e.g. a + // freshly-restored device before unlock) → show a LOCKED state, not blank dashes. + if (mine == null) { + _uiState.update { it.copy(phase = ReflectionPhase.LOCKED) } + return + } + if (!revealedMarked) { + revealedMarked = true + runCatching { reflectionDataSource.markRevealed(cid, dateId, uid) } + } _uiState.update { it.copy(phase = ReflectionPhase.REVEALED, mine = mine, partner = partner) } } } } - fun onFavoriteMoment(v: String) = _uiState.update { it.copy(favoriteMoment = v) } - fun onSurprise(v: String) = _uiState.update { it.copy(surprise = v) } - fun onAppreciated(v: String) = _uiState.update { it.copy(appreciated = v) } + fun onFavoriteMoment(v: String) = _uiState.update { it.copy(favoriteMoment = v.take(MAX_PROMPT_LEN), error = null) } + fun onSurprise(v: String) = _uiState.update { it.copy(surprise = v.take(MAX_PROMPT_LEN), error = null) } + fun onAppreciated(v: String) = _uiState.update { it.copy(appreciated = v.take(MAX_PROMPT_LEN), error = null) } + fun onNotes(v: String) = _uiState.update { it.copy(notes = v.take(MAX_NOTES_LEN), error = null) } + + /** Re-open the editor pre-filled to edit a still-sealed reflection (before the partner reflects). */ + fun startEdit() { + val mine = _uiState.value.mine ?: return + _uiState.update { + it.copy( + phase = ReflectionPhase.EDIT, + isEditing = true, + favoriteMoment = mine.favoriteMoment, + surprise = mine.surprise, + appreciated = mine.appreciated, + notes = mine.notes, + error = null + ) + } + } fun save() { val state = _uiState.value @@ -145,28 +193,31 @@ class DateReflectionViewModel @Inject constructor( val cid = coupleId val uid = authRepository.currentUserId if (cid == null || uid == null) return - if (state.favoriteMoment.isBlank() && state.surprise.isBlank() && state.appreciated.isBlank()) { + if (state.favoriteMoment.isBlank() && state.surprise.isBlank() && + state.appreciated.isBlank() && state.notes.isBlank() + ) { _uiState.update { it.copy(error = "Add at least one reflection first.") } return } _uiState.update { it.copy(isSaving = true, error = null) } + val editing = state.isEditing viewModelScope.launch { + val reflection = DateReflection( + dateId = dateId, userId = uid, + favoriteMoment = state.favoriteMoment.trim(), + surprise = state.surprise.trim(), + appreciated = state.appreciated.trim(), + notes = state.notes.trim() + ) runCatching { - reflectionDataSource.saveReflection( - cid, dateId, uid, - DateReflection( - dateId = dateId, userId = uid, - favoriteMoment = state.favoriteMoment.trim(), - surprise = state.surprise.trim(), - appreciated = state.appreciated.trim() - ) - ) + if (editing) reflectionDataSource.updateReflection(cid, dateId, uid, reflection) + else reflectionDataSource.saveReflection(cid, dateId, uid, reflection) }.onFailure { crashReporter.recordException(it) _uiState.update { s -> s.copy(isSaving = false, error = "Couldn't save. Try again.") } return@launch } - _uiState.update { it.copy(isSaving = false) } + _uiState.update { it.copy(isSaving = false, isEditing = false) } refresh() } } @@ -183,20 +234,32 @@ fun DateReflectionScreen( SettingsSubpage(title = "Date reflection", onBack = { onNavigate("back") }) { padding -> when (state.phase) { ReflectionPhase.LOADING -> Box(Modifier.fillMaxSize().padding(padding), Alignment.Center) { CloserHeartLoader() } - ReflectionPhase.ERROR -> Box(Modifier.fillMaxSize().padding(padding), Alignment.Center) { - Text(state.error ?: "Something went wrong.", color = MaterialTheme.colorScheme.onSurfaceVariant) - } + ReflectionPhase.ERROR -> CenteredMessage(padding, state.error ?: "Something went wrong.") + ReflectionPhase.LOCKED -> CenteredMessage( + padding, + "Locked — unlock your vault on this device to view these reflections." + ) else -> Column( modifier = Modifier .fillMaxSize() .padding(padding) + .imePadding() + .navigationBarsPadding() .verticalScroll(rememberScrollState()) .padding(horizontal = 20.dp, vertical = 12.dp), verticalArrangement = Arrangement.spacedBy(14.dp) ) { + state.dateTitle?.let { + Text( + it, + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.SemiBold, + color = MaterialTheme.colorScheme.onSurface + ) + } when (state.phase) { ReflectionPhase.EDIT -> ReflectionEditor(state, viewModel) - ReflectionPhase.AWAITING_PARTNER -> AwaitingPartner(state) + ReflectionPhase.AWAITING_PARTNER -> AwaitingPartner(state, viewModel) ReflectionPhase.REVEALED -> RevealedReflections(state) else -> {} } @@ -207,32 +270,54 @@ fun DateReflectionScreen( } @Composable -private fun ReflectionEditor(state: DateReflectionUiState, viewModel: DateReflectionViewModel) { - Text( - "Reflect privately — your words stay sealed until you've both shared.", - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - OutlinedTextField( - value = state.favoriteMoment, onValueChange = viewModel::onFavoriteMoment, - label = { Text(REFLECTION_PROMPTS[0]) }, modifier = Modifier.fillMaxWidth(), minLines = 2 - ) - OutlinedTextField( - value = state.surprise, onValueChange = viewModel::onSurprise, - label = { Text(REFLECTION_PROMPTS[1]) }, modifier = Modifier.fillMaxWidth(), minLines = 2 - ) - OutlinedTextField( - value = state.appreciated, onValueChange = viewModel::onAppreciated, - label = { Text(REFLECTION_PROMPTS[2]) }, modifier = Modifier.fillMaxWidth(), minLines = 2 - ) - state.error?.let { Text(it, color = MaterialTheme.colorScheme.error, style = MaterialTheme.typography.bodySmall) } - Button(onClick = viewModel::save, enabled = !state.isSaving, modifier = Modifier.fillMaxWidth()) { - Text(if (state.isSaving) "Saving…" else "Save my reflection") +private fun CenteredMessage(padding: androidx.compose.foundation.layout.PaddingValues, message: String) { + Box(Modifier.fillMaxSize().padding(padding).padding(horizontal = 24.dp), Alignment.Center) { + Text( + message, + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurfaceVariant, + textAlign = TextAlign.Center + ) } } @Composable -private fun AwaitingPartner(state: DateReflectionUiState) { +private fun ReflectionEditor(state: DateReflectionUiState, viewModel: DateReflectionViewModel) { + Text( + "Reflect privately — once you save, it's sealed until you both reveal together.", + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + ReflectionField(state.favoriteMoment, viewModel::onFavoriteMoment, REFLECTION_PROMPTS[0], MAX_PROMPT_LEN, minLines = 2) + ReflectionField(state.surprise, viewModel::onSurprise, REFLECTION_PROMPTS[1], MAX_PROMPT_LEN, minLines = 2) + ReflectionField(state.appreciated, viewModel::onAppreciated, REFLECTION_PROMPTS[2], MAX_PROMPT_LEN, minLines = 2) + ReflectionField(state.notes, viewModel::onNotes, REFLECTION_PROMPTS[3], MAX_NOTES_LEN, minLines = 3) + state.error?.let { Text(it, color = MaterialTheme.colorScheme.error, style = MaterialTheme.typography.bodySmall) } + Button(onClick = viewModel::save, enabled = !state.isSaving, modifier = Modifier.fillMaxWidth()) { + Text(if (state.isSaving) "Saving…" else if (state.isEditing) "Update my reflection" else "Save my reflection") + } +} + +@Composable +private fun ReflectionField( + value: String, + onValueChange: (String) -> Unit, + label: String, + maxLen: Int, + minLines: Int +) { + OutlinedTextField( + value = value, + onValueChange = onValueChange, + label = { Text(label) }, + modifier = Modifier.fillMaxWidth(), + minLines = minLines, + supportingText = { Text("${value.length}/$maxLen") } + ) +} + +@Composable +private fun AwaitingPartner(state: DateReflectionUiState, viewModel: DateReflectionViewModel) { Text( "Saved privately 💜 — waiting for ${state.partnerName} to reflect. You'll reveal together.", style = MaterialTheme.typography.bodyLarge, @@ -240,6 +325,9 @@ private fun AwaitingPartner(state: DateReflectionUiState) { color = MaterialTheme.colorScheme.onSurface ) state.mine?.let { ReflectionCard(title = "Your reflection", reflection = it) } + OutlinedButton(onClick = viewModel::startEdit, modifier = Modifier.fillMaxWidth()) { + Text("Edit my reflection") + } } @Composable @@ -282,5 +370,6 @@ private fun ReflectionCard(title: String, reflection: DateReflection) { private fun promptValue(r: DateReflection?, index: Int): String = when (index) { 0 -> r?.favoriteMoment.orEmpty() 1 -> r?.surprise.orEmpty() - else -> r?.appreciated.orEmpty() + 2 -> r?.appreciated.orEmpty() + else -> r?.notes.orEmpty() } diff --git a/app/src/main/java/app/closer/ui/home/HomeViewModel.kt b/app/src/main/java/app/closer/ui/home/HomeViewModel.kt index 577a8e03..d78e63c5 100644 --- a/app/src/main/java/app/closer/ui/home/HomeViewModel.kt +++ b/app/src/main/java/app/closer/ui/home/HomeViewModel.kt @@ -388,14 +388,14 @@ class HomeViewModel @Inject constructor( .any { it.status == "sealed" && it.unlockAt in 1L..now } }.getOrDefault(false) } - // Pending date reflection: the most recent completed date this user hasn't - // reflected on yet. The nudge chases the latest date; older un-reflected dates - // remain reachable from the Replay timeline. + // Pending date reflection: true if ANY recent completed date still lacks this + // user's reflection (not just the latest), so an older un-reflected date keeps + // nudging too. Bounded to the most recent dates to cap the reads. val reflectionJob = async { runCatching { - val latest = dateMemoryDataSource.getHistoryOnce(coupleId).firstOrNull() - latest != null && - !dateReflectionDataSource.hasReflected(coupleId, latest.id, uid) + dateMemoryDataSource.getHistoryOnce(coupleId) + .take(RECENT_DATES_FOR_REFLECTION_NUDGE) + .any { !dateReflectionDataSource.hasReflected(coupleId, it.id, uid) } }.getOrDefault(false) } val (waitingSession, waitingRoute) = gameJob.await() @@ -970,5 +970,7 @@ class HomeViewModel @Inject constructor( companion object { private const val TAG = "HomeViewModel" private val STREAK_MILESTONES = listOf(7, 30, 100, 365) + // How many recent completed dates the reflection nudge scans for an un-reflected one. + private const val RECENT_DATES_FOR_REFLECTION_NUDGE = 10 } } diff --git a/firestore.rules b/firestore.rules index 6e47fbf1..8cf156e3 100644 --- a/firestore.rules +++ b/firestore.rules @@ -18,6 +18,19 @@ service cloud.firestore { get(/databases/$(database)/documents/couples/$(coupleId)).data.userIds; } + // The other member of a 2-person couple (relative to uid). + function otherCoupleMember(coupleId, uid) { + return get(/databases/$(database)/documents/couples/$(coupleId)).data.userIds[0] == uid + ? get(/databases/$(database)/documents/couples/$(coupleId)).data.userIds[1] + : get(/databases/$(database)/documents/couples/$(coupleId)).data.userIds[0]; + } + + // Has the partner already written their reflection for this date? Once true, the author's + // reflection is sealed (edits are no longer allowed). + function partnerReflectedDate(coupleId, dateId, uid) { + return exists(/databases/$(database)/documents/couples/$(coupleId)/date_reflections/$(dateId)/answers/$(otherCoupleMember(coupleId, uid))); + } + function isValidInviteCode(code) { // Code must be exactly 6 alphanumeric characters return code.matches('^[a-zA-Z0-9]{6}$'); @@ -685,7 +698,14 @@ service cloud.firestore { && request.auth.uid == userId && isCiphertext(request.resource.data.encryptedPayload) && request.resource.data.keys().hasOnly(['encryptedPayload']); - allow update, delete: if false; + // Author may edit their OWN still-sealed reflection ONLY until the partner reflects. Once the + // partner has reflected the content is immutable (the "sealed until both reveal" guarantee). + allow update: if isCouplesMember(coupleId) + && request.auth.uid == userId + && !partnerReflectedDate(coupleId, dateId, userId) + && isCiphertext(request.resource.data.encryptedPayload) + && request.resource.data.keys().hasOnly(['encryptedPayload']); + allow delete: if false; } } diff --git a/functions/dist/dates/onDateReflectionRevealed.js b/functions/dist/dates/onDateReflectionRevealed.js new file mode 100644 index 00000000..66d10dc6 --- /dev/null +++ b/functions/dist/dates/onDateReflectionRevealed.js @@ -0,0 +1,111 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.onDateReflectionRevealed = void 0; +const functions = __importStar(require("firebase-functions")); +const admin = __importStar(require("firebase-admin")); +const quietHours_1 = require("../notifications/quietHours"); +const pruneTokens_1 = require("../notifications/pruneTokens"); +/** + * Fires when a partner OPENS (reveals) the shared date reflections — their own reflection metadata doc + * flips `isRevealed` false → true (`couples/{coupleId}/date_reflections/{dateId}/answers/{userId}`). + * Notifies the OTHER partner that their reflection was read, mirroring daily's `onAnswerRevealed`: + * generic copy (no decrypted content, no name — the app renders the real name in-app), gated on + * `notifPartnerAnswered` + quiet hours (push suppressed in quiet hours, but the in-app record is kept). + */ +exports.onDateReflectionRevealed = functions.firestore + .document('couples/{coupleId}/date_reflections/{dateId}/answers/{userId}') + .onUpdate(async (change, context) => { + var _a, _b, _c, _d, _e; + const { coupleId, dateId, userId } = context.params; + const before = change.before.data(); + const after = change.after.data(); + // Only on the false → true reveal transition. + if (before.isRevealed === true || after.isRevealed !== true) + return; + const db = admin.firestore(); + const coupleDoc = await db.collection('couples').doc(coupleId).get(); + if (!coupleDoc.exists) + return; + const userIds = ((_b = (_a = coupleDoc.data()) === null || _a === void 0 ? void 0 : _a.userIds) !== null && _b !== void 0 ? _b : []); + if (!userIds.includes(userId)) + return; + const partnerId = userIds.find((u) => u !== userId); + if (!partnerId) + return; + const partnerUserDoc = await db.collection('users').doc(partnerId).get(); + if (((_c = partnerUserDoc.data()) === null || _c === void 0 ? void 0 : _c.notifPartnerAnswered) === false) { + console.log(`[onDateReflectionRevealed] ${partnerId} has partner notifications off`); + return; + } + const title = 'Your partner opened your reflection ✨'; + const body = 'Open to see what you each wrote.'; + const type = 'date_reflection_opened'; + // In-app record (→ Together feed) — written regardless of quiet hours. + await db.collection('users').doc(partnerId).collection('notification_queue').add({ + type, title, body, read: false, createdAt: admin.firestore.FieldValue.serverTimestamp(), + }); + if ((0, quietHours_1.recipientInQuietHours)(partnerUserDoc.data())) { + console.log(`[onDateReflectionRevealed] ${partnerId} in quiet hours — push suppressed (in-app kept)`); + return; + } + const senderAvatar = (_d = (await db.collection('users').doc(userId).get()).data()) === null || _d === void 0 ? void 0 : _d.photoUrl; + const tokens = []; + const legacy = (_e = partnerUserDoc.data()) === null || _e === void 0 ? void 0 : _e.fcmToken; + if (typeof legacy === 'string' && legacy.length > 0) + tokens.push(legacy); + const tokenSnap = await db.collection('users').doc(partnerId).collection('fcmTokens').get(); + tokenSnap.docs.forEach((d) => { + var _a; + const t = (_a = d.data()) === null || _a === void 0 ? void 0 : _a.token; + if (typeof t === 'string' && t.length > 0 && !tokens.includes(t)) + tokens.push(t); + }); + if (tokens.length === 0) + return; + const payload = { + notification: { title, body }, + data: Object.assign({ type, couple_id: coupleId, date_id: dateId }, (typeof senderAvatar === 'string' && senderAvatar.length > 0 + ? { sender_avatar_url: senderAvatar } + : {})), + }; + const results = await Promise.allSettled(tokens.map((token) => admin.messaging().send(Object.assign(Object.assign({}, payload), { token, android: { notification: { channelId: 'partner_activity' } } })))); + results.forEach((r, i) => { + if (r.status === 'rejected') + console.warn(`[onDateReflectionRevealed] FCM failed for ${tokens[i]}:`, r.reason); + }); + await (0, pruneTokens_1.pruneDeadTokens)(db, partnerId, tokens, results); +}); +//# sourceMappingURL=onDateReflectionRevealed.js.map \ No newline at end of file diff --git a/functions/dist/dates/onDateReflectionRevealed.js.map b/functions/dist/dates/onDateReflectionRevealed.js.map new file mode 100644 index 00000000..568062ae --- /dev/null +++ b/functions/dist/dates/onDateReflectionRevealed.js.map @@ -0,0 +1 @@ +{"version":3,"file":"onDateReflectionRevealed.js","sourceRoot":"","sources":["../../src/dates/onDateReflectionRevealed.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8DAA+C;AAC/C,sDAAuC;AACvC,4DAAmE;AACnE,8DAA8D;AAE9D;;;;;;GAMG;AACU,QAAA,wBAAwB,GAAG,SAAS,CAAC,SAAS;KACxD,QAAQ,CAAC,+DAA+D,CAAC;KACzE,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;;IAClC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAI5C,CAAA;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAsC,CAAA;IACvE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,EAAsC,CAAA;IACrE,8CAA8C;IAC9C,IAAI,MAAM,CAAC,UAAU,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI;QAAE,OAAM;IAEnE,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;IAE5B,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAA;IACpE,IAAI,CAAC,SAAS,CAAC,MAAM;QAAE,OAAM;IAC7B,MAAM,OAAO,GAAG,CAAC,MAAA,MAAA,SAAS,CAAC,IAAI,EAAE,0CAAE,OAAO,mCAAI,EAAE,CAAa,CAAA;IAC7D,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAM;IACrC,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,CAAA;IACnD,IAAI,CAAC,SAAS;QAAE,OAAM;IAEtB,MAAM,cAAc,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,CAAA;IACxE,IAAI,CAAA,MAAA,cAAc,CAAC,IAAI,EAAE,0CAAE,oBAAoB,MAAK,KAAK,EAAE,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,8BAA8B,SAAS,gCAAgC,CAAC,CAAA;QACpF,OAAM;IACR,CAAC;IAED,MAAM,KAAK,GAAG,uCAAuC,CAAA;IACrD,MAAM,IAAI,GAAG,kCAAkC,CAAA;IAC/C,MAAM,IAAI,GAAG,wBAAwB,CAAA;IAErC,uEAAuE;IACvE,MAAM,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC;QAC/E,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,eAAe,EAAE;KACxF,CAAC,CAAA;IAEF,IAAI,IAAA,kCAAqB,EAAC,cAAc,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,8BAA8B,SAAS,iDAAiD,CAAC,CAAA;QACrG,OAAM;IACR,CAAC;IAED,MAAM,YAAY,GAAG,MAAA,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,0CAAE,QAAQ,CAAA;IAEtF,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,MAAM,MAAM,GAAG,MAAA,cAAc,CAAC,IAAI,EAAE,0CAAE,QAAQ,CAAA;IAC9C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACxE,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,GAAG,EAAE,CAAA;IAC3F,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;;QAC3B,MAAM,CAAC,GAAG,MAAA,CAAC,CAAC,IAAI,EAAE,0CAAE,KAAK,CAAA;QACzB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAClF,CAAC,CAAC,CAAA;IACF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IAE/B,MAAM,OAAO,GAAqC;QAChD,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;QAC7B,IAAI,kBACF,IAAI,EACJ,SAAS,EAAE,QAAQ,EACnB,OAAO,EAAE,MAAM,IACZ,CAAC,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC;YAC7D,CAAC,CAAC,EAAE,iBAAiB,EAAE,YAAY,EAAE;YACrC,CAAC,CAAC,EAAE,CAAC,CACR;KACF,CAAA;IACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACnB,KAAK,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,gCAClB,OAAO,KACV,KAAK,EACL,OAAO,EAAE,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE,GAClC,CAAC,CAC9B,CACF,CAAA;IACD,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACvB,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU;YAAE,OAAO,CAAC,IAAI,CAAC,6CAA6C,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAA;IAChH,CAAC,CAAC,CAAA;IACF,MAAM,IAAA,6BAAe,EAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;AACvD,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/functions/dist/index.js b/functions/dist/index.js index fc583f1f..9995d360 100644 --- a/functions/dist/index.js +++ b/functions/dist/index.js @@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -exports.wrapReleaseKeyCallable = exports.onGamePartFinished = exports.onGameSessionUpdate = exports.onUserDelete = exports.scheduledOutcomesReminder = exports.submitOutcomeCallable = exports.createInviteCallable = exports.acceptInviteCallable = exports.leaveCoupleCallable = exports.onCoupleLeave = exports.onMessageWritten = exports.onAnswerRevealed = exports.onAnswerWritten = exports.assignDailyQuestionCallable = exports.assignDailyQuestion = exports.onRestoreFulfilled = exports.onRestoreRequested = exports.onDateHistoryCreated = exports.onDateReflectionWritten = exports.notifyOnDateMatch = exports.checkDeviceIntegrity = exports.sendReengagementReminder = exports.sendStreakReminder = exports.sendDailyQuestionProactiveReminder = exports.unlockDueMemoryCapsules = exports.sendChallengeDayReminders = exports.sendThinkingOfYouCallable = exports.sendGentleReminderCallable = exports.sendPartnerAnsweredNotification = exports.sendDailyQuestionReminder = exports.onEntitlementChanged = exports.syncEntitlement = exports.revenueCatWebhook = void 0; +exports.wrapReleaseKeyCallable = exports.onGamePartFinished = exports.onGameSessionUpdate = exports.onUserDelete = exports.scheduledOutcomesReminder = exports.submitOutcomeCallable = exports.createInviteCallable = exports.acceptInviteCallable = exports.leaveCoupleCallable = exports.onCoupleLeave = exports.onMessageWritten = exports.onAnswerRevealed = exports.onAnswerWritten = exports.assignDailyQuestionCallable = exports.assignDailyQuestion = exports.onRestoreFulfilled = exports.onRestoreRequested = exports.onDateHistoryCreated = exports.onDateReflectionRevealed = exports.onDateReflectionWritten = exports.notifyOnDateMatch = exports.checkDeviceIntegrity = exports.sendReengagementReminder = exports.sendStreakReminder = exports.sendDailyQuestionProactiveReminder = exports.unlockDueMemoryCapsules = exports.sendChallengeDayReminders = exports.sendThinkingOfYouCallable = exports.sendGentleReminderCallable = exports.sendPartnerAnsweredNotification = exports.sendDailyQuestionReminder = exports.onEntitlementChanged = exports.syncEntitlement = exports.revenueCatWebhook = void 0; const admin = __importStar(require("firebase-admin")); // Initialize the Admin SDK once for every function in this codebase. // Handlers call admin.firestore()/messaging() lazily at invocation time, so a @@ -69,6 +69,8 @@ var createDateMatch_1 = require("./dates/createDateMatch"); Object.defineProperty(exports, "notifyOnDateMatch", { enumerable: true, get: function () { return createDateMatch_1.notifyOnDateMatch; } }); var onDateReflectionWritten_1 = require("./dates/onDateReflectionWritten"); Object.defineProperty(exports, "onDateReflectionWritten", { enumerable: true, get: function () { return onDateReflectionWritten_1.onDateReflectionWritten; } }); +var onDateReflectionRevealed_1 = require("./dates/onDateReflectionRevealed"); +Object.defineProperty(exports, "onDateReflectionRevealed", { enumerable: true, get: function () { return onDateReflectionRevealed_1.onDateReflectionRevealed; } }); var onDateHistoryCreated_1 = require("./dates/onDateHistoryCreated"); Object.defineProperty(exports, "onDateHistoryCreated", { enumerable: true, get: function () { return onDateHistoryCreated_1.onDateHistoryCreated; } }); var onRestoreRequested_1 = require("./backup/onRestoreRequested"); diff --git a/functions/dist/index.js.map b/functions/dist/index.js.map index ea70fe5c..8155709c 100644 --- a/functions/dist/index.js.map +++ b/functions/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sDAAuC;AAEvC,qEAAqE;AACrE,8EAA8E;AAC9E,gFAAgF;AAChF,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAC5B,KAAK,CAAC,aAAa,EAAE,CAAA;AACvB,CAAC;AAED,iEAA+D;AAAtD,sHAAA,iBAAiB,OAAA;AAC1B,6DAA2D;AAAlD,kHAAA,eAAe,OAAA;AACxB,uEAAqE;AAA5D,4HAAA,oBAAoB,OAAA;AAC7B,uDAGkC;AAFhC,sHAAA,yBAAyB,OAAA;AACzB,4HAAA,+BAA+B,OAAA;AAEjC,yFAAuF;AAA9E,wIAAA,0BAA0B,OAAA;AACnC,uFAAqF;AAA5E,sIAAA,yBAAyB,OAAA;AAClC,+DAGsC;AAFpC,0HAAA,yBAAyB,OAAA;AACzB,wHAAA,uBAAuB,OAAA;AAEzB,+EAA0F;AAAjF,2IAAA,kCAAkC,OAAA;AAC3C,iEAAmE;AAA1D,oHAAA,kBAAkB,OAAA;AAC3B,6DAAuE;AAA9D,wHAAA,wBAAwB,OAAA;AACjC,wEAAsE;AAA7D,4HAAA,oBAAoB,OAAA;AAC7B,2DAA2D;AAAlD,oHAAA,iBAAiB,OAAA;AAC1B,2EAAyE;AAAhE,kIAAA,uBAAuB,OAAA;AAChC,qEAAmE;AAA1D,4HAAA,oBAAoB,OAAA;AAC7B,kEAAoF;AAA3E,wHAAA,kBAAkB,OAAA;AAAE,wHAAA,kBAAkB,OAAA;AAC/C,uEAGwC;AAFtC,0HAAA,mBAAmB,OAAA;AACnB,kIAAA,2BAA2B,OAAA;AAE7B,+DAA6D;AAApD,kHAAA,eAAe,OAAA;AACxB,iEAA+D;AAAtD,oHAAA,gBAAgB,OAAA;AACzB,iEAA+D;AAAtD,oHAAA,gBAAgB,OAAA;AACzB,yDAAuD;AAA9C,8GAAA,aAAa,OAAA;AACtB,qEAAmE;AAA1D,0HAAA,mBAAmB,OAAA;AAC5B,uEAAqE;AAA5D,4HAAA,oBAAoB,OAAA;AAC7B,uEAAqE;AAA5D,4HAAA,oBAAoB,OAAA;AAC7B,yEAAuE;AAA9D,8HAAA,qBAAqB,OAAA;AAC9B,iFAA+E;AAAtE,sIAAA,yBAAyB,OAAA;AAClC,qDAAmD;AAA1C,4GAAA,YAAY,OAAA;AACrB,mEAAqF;AAA5E,0HAAA,mBAAmB,OAAA;AAAE,yHAAA,kBAAkB,OAAA;AAEhD,8EAA4E;AAAnE,gIAAA,sBAAsB,OAAA;AAE/B,oFAAoF;AACpF,uEAAuE;AACvE,iFAAiF;AACjF,0DAA0D"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sDAAuC;AAEvC,qEAAqE;AACrE,8EAA8E;AAC9E,gFAAgF;AAChF,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAC5B,KAAK,CAAC,aAAa,EAAE,CAAA;AACvB,CAAC;AAED,iEAA+D;AAAtD,sHAAA,iBAAiB,OAAA;AAC1B,6DAA2D;AAAlD,kHAAA,eAAe,OAAA;AACxB,uEAAqE;AAA5D,4HAAA,oBAAoB,OAAA;AAC7B,uDAGkC;AAFhC,sHAAA,yBAAyB,OAAA;AACzB,4HAAA,+BAA+B,OAAA;AAEjC,yFAAuF;AAA9E,wIAAA,0BAA0B,OAAA;AACnC,uFAAqF;AAA5E,sIAAA,yBAAyB,OAAA;AAClC,+DAGsC;AAFpC,0HAAA,yBAAyB,OAAA;AACzB,wHAAA,uBAAuB,OAAA;AAEzB,+EAA0F;AAAjF,2IAAA,kCAAkC,OAAA;AAC3C,iEAAmE;AAA1D,oHAAA,kBAAkB,OAAA;AAC3B,6DAAuE;AAA9D,wHAAA,wBAAwB,OAAA;AACjC,wEAAsE;AAA7D,4HAAA,oBAAoB,OAAA;AAC7B,2DAA2D;AAAlD,oHAAA,iBAAiB,OAAA;AAC1B,2EAAyE;AAAhE,kIAAA,uBAAuB,OAAA;AAChC,6EAA2E;AAAlE,oIAAA,wBAAwB,OAAA;AACjC,qEAAmE;AAA1D,4HAAA,oBAAoB,OAAA;AAC7B,kEAAoF;AAA3E,wHAAA,kBAAkB,OAAA;AAAE,wHAAA,kBAAkB,OAAA;AAC/C,uEAGwC;AAFtC,0HAAA,mBAAmB,OAAA;AACnB,kIAAA,2BAA2B,OAAA;AAE7B,+DAA6D;AAApD,kHAAA,eAAe,OAAA;AACxB,iEAA+D;AAAtD,oHAAA,gBAAgB,OAAA;AACzB,iEAA+D;AAAtD,oHAAA,gBAAgB,OAAA;AACzB,yDAAuD;AAA9C,8GAAA,aAAa,OAAA;AACtB,qEAAmE;AAA1D,0HAAA,mBAAmB,OAAA;AAC5B,uEAAqE;AAA5D,4HAAA,oBAAoB,OAAA;AAC7B,uEAAqE;AAA5D,4HAAA,oBAAoB,OAAA;AAC7B,yEAAuE;AAA9D,8HAAA,qBAAqB,OAAA;AAC9B,iFAA+E;AAAtE,sIAAA,yBAAyB,OAAA;AAClC,qDAAmD;AAA1C,4GAAA,YAAY,OAAA;AACrB,mEAAqF;AAA5E,0HAAA,mBAAmB,OAAA;AAAE,yHAAA,kBAAkB,OAAA;AAEhD,8EAA4E;AAAnE,gIAAA,sBAAsB,OAAA;AAE/B,oFAAoF;AACpF,uEAAuE;AACvE,iFAAiF;AACjF,0DAA0D"} \ No newline at end of file diff --git a/functions/src/dates/onDateReflectionRevealed.ts b/functions/src/dates/onDateReflectionRevealed.ts new file mode 100644 index 00000000..70a59a71 --- /dev/null +++ b/functions/src/dates/onDateReflectionRevealed.ts @@ -0,0 +1,92 @@ +import * as functions from 'firebase-functions' +import * as admin from 'firebase-admin' +import { recipientInQuietHours } from '../notifications/quietHours' +import { pruneDeadTokens } from '../notifications/pruneTokens' + +/** + * Fires when a partner OPENS (reveals) the shared date reflections — their own reflection metadata doc + * flips `isRevealed` false → true (`couples/{coupleId}/date_reflections/{dateId}/answers/{userId}`). + * Notifies the OTHER partner that their reflection was read, mirroring daily's `onAnswerRevealed`: + * generic copy (no decrypted content, no name — the app renders the real name in-app), gated on + * `notifPartnerAnswered` + quiet hours (push suppressed in quiet hours, but the in-app record is kept). + */ +export const onDateReflectionRevealed = functions.firestore + .document('couples/{coupleId}/date_reflections/{dateId}/answers/{userId}') + .onUpdate(async (change, context) => { + const { coupleId, dateId, userId } = context.params as { + coupleId: string + dateId: string + userId: string + } + + const before = change.before.data() as Partial> + const after = change.after.data() as Partial> + // Only on the false → true reveal transition. + if (before.isRevealed === true || after.isRevealed !== true) return + + const db = admin.firestore() + + const coupleDoc = await db.collection('couples').doc(coupleId).get() + if (!coupleDoc.exists) return + const userIds = (coupleDoc.data()?.userIds ?? []) as string[] + if (!userIds.includes(userId)) return + const partnerId = userIds.find((u) => u !== userId) + if (!partnerId) return + + const partnerUserDoc = await db.collection('users').doc(partnerId).get() + if (partnerUserDoc.data()?.notifPartnerAnswered === false) { + console.log(`[onDateReflectionRevealed] ${partnerId} has partner notifications off`) + return + } + + const title = 'Your partner opened your reflection ✨' + const body = 'Open to see what you each wrote.' + const type = 'date_reflection_opened' + + // In-app record (→ Together feed) — written regardless of quiet hours. + await db.collection('users').doc(partnerId).collection('notification_queue').add({ + type, title, body, read: false, createdAt: admin.firestore.FieldValue.serverTimestamp(), + }) + + if (recipientInQuietHours(partnerUserDoc.data())) { + console.log(`[onDateReflectionRevealed] ${partnerId} in quiet hours — push suppressed (in-app kept)`) + return + } + + const senderAvatar = (await db.collection('users').doc(userId).get()).data()?.photoUrl + + const tokens: string[] = [] + const legacy = partnerUserDoc.data()?.fcmToken + if (typeof legacy === 'string' && legacy.length > 0) tokens.push(legacy) + const tokenSnap = await db.collection('users').doc(partnerId).collection('fcmTokens').get() + tokenSnap.docs.forEach((d) => { + const t = d.data()?.token + if (typeof t === 'string' && t.length > 0 && !tokens.includes(t)) tokens.push(t) + }) + if (tokens.length === 0) return + + const payload: admin.messaging.MessagingPayload = { + notification: { title, body }, + data: { + type, + couple_id: coupleId, + date_id: dateId, + ...(typeof senderAvatar === 'string' && senderAvatar.length > 0 + ? { sender_avatar_url: senderAvatar } + : {}), + }, + } + const results = await Promise.allSettled( + tokens.map((token) => + admin.messaging().send({ + ...payload, + token, + android: { notification: { channelId: 'partner_activity' } }, + } as admin.messaging.Message) + ) + ) + results.forEach((r, i) => { + if (r.status === 'rejected') console.warn(`[onDateReflectionRevealed] FCM failed for ${tokens[i]}:`, r.reason) + }) + await pruneDeadTokens(db, partnerId, tokens, results) + }) diff --git a/functions/src/index.ts b/functions/src/index.ts index 4bccc9e0..e65ed772 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -26,6 +26,7 @@ export { sendReengagementReminder } from './notifications/reengagement' export { checkDeviceIntegrity } from './security/checkDeviceIntegrity' export { notifyOnDateMatch } from './dates/createDateMatch' export { onDateReflectionWritten } from './dates/onDateReflectionWritten' +export { onDateReflectionRevealed } from './dates/onDateReflectionRevealed' export { onDateHistoryCreated } from './dates/onDateHistoryCreated' export { onRestoreRequested, onRestoreFulfilled } from './backup/onRestoreRequested' export { diff --git a/scripts/ime-scan.sh b/scripts/ime-scan.sh new file mode 100755 index 00000000..0e60bc73 --- /dev/null +++ b/scripts/ime-scan.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# +# CloserApp — IME/keyboard-handling scanner (Pass J pre-check) +# +# WHY: the app is edge-to-edge (WindowCompat, decorFitsSystemWindows=false) with +# windowSoftInputMode=adjustResize. Under edge-to-edge the window does NOT physically resize, so any +# screen with a text field must reserve keyboard space via WindowInsets — `imePadding()` or +# `safeDrawingPadding()` — or the soft keyboard overlays the fields and they can't be typed into. +# This scanner caught DateReflectionScreen shipping without it ("you can't type in Date Reflection"). +# +# It flags every file containing a text field (OutlinedTextField / BasicTextField / TextField) that does +# NOT itself call imePadding()/safeDrawingPadding(). Reusable *components* that are always hosted inside an +# IME-handling screen are allowlisted below (verify the host still handles IME before adding one). +# +# ⛔ CLAUDE: keep this runnable from the project root; update the allowlist ONLY after confirming the +# component's host screens handle IME. Exit code is non-zero if any non-allowlisted file is missing. +# +# Usage: ./scripts/ime-scan.sh +set -euo pipefail + +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +UI_DIR="$PROJECT_ROOT/app/src/main/java/app/closer/ui" + +# Components whose IME handling is provided by their host screen (verified). Basenames only. +ALLOWLIST=( + "QuestionAnswerInput.kt" # hosted by QuestionThreadScreen (imePadding) + LocalQuestionContent (safeDrawingPadding) + "QuestionDiscussionThread.kt" # hosted by QuestionThreadScreen (imePadding) +) + +is_allowlisted() { + local base="$1" + for a in "${ALLOWLIST[@]}"; do [[ "$base" == "$a" ]] && return 0; done + return 1 +} + +fail=0 +printf '=== IME/keyboard-handling scan (text-input screens) ===\n\n' + +# Files with any text-input composable. +mapfile -t files < <(grep -rlE "OutlinedTextField\(|BasicTextField\(| TextField\(" "$UI_DIR" 2>/dev/null | sort) + +for f in "${files[@]}"; do + base="$(basename "$f")" + rel="${f#"$PROJECT_ROOT"/}" + if grep -qE "imePadding|safeDrawingPadding" "$f"; then + printf ' OK %s\n' "$rel" + elif is_allowlisted "$base"; then + printf ' OK(host) %s (component; host handles IME)\n' "$rel" + else + printf ' ** MISSING IME ** %s\n' "$rel" + fail=1 + fi +done + +echo +if [[ "$fail" -ne 0 ]]; then + echo "FAIL: one or more text-input screens lack imePadding()/safeDrawingPadding()." + echo "Add IME handling to the scrollable content Column (see e.g. ConversationScreen.kt), or allowlist" + echo "the file here ONLY if it is a component whose host screen already handles IME." + exit 1 +fi +echo "PASS: every text-input screen handles the keyboard." diff --git a/seed/questions/date_night.json b/seed/questions/date_night.json index e864db14..54574da2 100644 --- a/seed/questions/date_night.json +++ b/seed/questions/date_night.json @@ -2,17 +2,18 @@ "category": { "id": "date_night", "display_name": "Date Night", - "description": "Warm, low-pressure prompts for planning dates, enjoying time together, and making ordinary moments feel intentional.", + "description": "Grounded, fun date-night prompts for real couples: playful choices, low-pressure plans, flirty moments, and date ideas that do not feel like therapy homework or random snack clown content.", "access": "mixed", + "icon_name": "calendar_heart", "total_questions": 250, "free_questions": 75, "premium_questions": 175, "question_type_counts": { - "written": 150, - "single_choice": 40, - "multi_choice": 20, - "scale": 25, - "this_or_that": 15 + "multi_choice": 140, + "single_choice": 50, + "scale": 35, + "this_or_that": 15, + "written": 10 }, "schema_version": "question_v2", "supported_types": [ @@ -21,5563 +22,12179 @@ "multi_choice", "scale", "this_or_that" - ] + ], + "content_policy": { + "voice": "warm, specific, date-like, and lightly playful without sounding childish", + "target_mix": "standard 250-pack mix from QUESTION_CONTENT_GUIDE", + "review_version": "date_night_v7_grounded_fun_reviewed", + "patch_policy": "v7 patches v6 scale prompt rhythm and validation report after user flagged v5 as too childish.", + "hard_avoid": [ + "therapy voice", + "household admin", + "chores", + "tax-form planning", + "random snack circus", + "fake trophy overuse", + "awkward joke prompts" + ], + "format_rules": [ + "use concrete date choices a couple could actually do", + "keep playfulness mature and natural", + "make options answer the question directly", + "avoid making every prompt a tiny mission or snack bit" + ] + } }, "questions": [ { "id": "date_night_001", "category_id": "date_night", - "type": "written", - "text": "What is a simple date we could do this week without much planning?", + "type": "single_choice", + "text": "Which date sounds most like us this week?", "depth": 1, "access": "free", "tags": [ - "easy_dates", - "planning" + "date_night", + "single_choice", + "weekly_date" + ], + "options": [ + { + "id": "a", + "text": "Dinner at a familiar favorite" + }, + { + "id": "b", + "text": "A walk with coffee" + }, + { + "id": "c", + "text": "Trying one new place" + }, + { + "id": "d", + "text": "Staying in with a real plan" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Dinner at a familiar favorite" + }, + { + "id": "b", + "text": "A walk with coffee" + }, + { + "id": "c", + "text": "Trying one new place" + }, + { + "id": "d", + "text": "Staying in with a real plan" + } + ] } }, { "id": "date_night_002", "category_id": "date_night", - "type": "written", - "text": "What would make an ordinary night together feel a little more special?", + "type": "single_choice", + "text": "What would make tonight feel more like a date?", "depth": 1, "access": "free", "tags": [ - "simple_dates", - "special" + "date_night", + "single_choice", + "tonight" + ], + "options": [ + { + "id": "a", + "text": "Getting ready a little" + }, + { + "id": "b", + "text": "Choosing food together" + }, + { + "id": "c", + "text": "Starting at a real time" + }, + { + "id": "d", + "text": "Putting phones away for the first hour" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Getting ready a little" + }, + { + "id": "b", + "text": "Choosing food together" + }, + { + "id": "c", + "text": "Starting at a real time" + }, + { + "id": "d", + "text": "Putting phones away for the first hour" + } + ] } }, { "id": "date_night_003", "category_id": "date_night", - "type": "written", - "text": "What is your favorite kind of low-effort date with me?", + "type": "single_choice", + "text": "If we only plan one thing, what should it be?", "depth": 1, "access": "free", "tags": [ - "easy_dates", - "preference" + "date_night", + "single_choice", + "simple_plan" + ], + "options": [ + { + "id": "a", + "text": "Where we eat" + }, + { + "id": "b", + "text": "What we watch" + }, + { + "id": "c", + "text": "Where we walk" + }, + { + "id": "d", + "text": "What dessert we split" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Where we eat" + }, + { + "id": "b", + "text": "What we watch" + }, + { + "id": "c", + "text": "Where we walk" + }, + { + "id": "d", + "text": "What dessert we split" + } + ] } }, { "id": "date_night_004", "category_id": "date_night", - "type": "written", - "text": "What snack or drink would make a movie night feel complete?", + "type": "single_choice", + "text": "Which low-effort date would still feel intentional?", "depth": 1, "access": "free", "tags": [ - "movie_night", - "food" + "date_night", + "single_choice", + "low_effort" + ], + "options": [ + { + "id": "a", + "text": "Takeout with candles" + }, + { + "id": "b", + "text": "A coffee walk" + }, + { + "id": "c", + "text": "A shared playlist night" + }, + { + "id": "d", + "text": "Dessert somewhere close" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Takeout with candles" + }, + { + "id": "b", + "text": "A coffee walk" + }, + { + "id": "c", + "text": "A shared playlist night" + }, + { + "id": "d", + "text": "Dessert somewhere close" + } + ] } }, { "id": "date_night_005", "category_id": "date_night", - "type": "written", - "text": "What is a small at-home date we could repeat often?", + "type": "single_choice", + "text": "What kind of date mood fits us right now?", "depth": 1, "access": "free", "tags": [ - "home_date", - "repeat" + "date_night", + "single_choice", + "mood" + ], + "options": [ + { + "id": "a", + "text": "Easy and cozy" + }, + { + "id": "b", + "text": "Flirty and dressed up" + }, + { + "id": "c", + "text": "Curious and new" + }, + { + "id": "d", + "text": "Quiet and unrushed" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Easy and cozy" + }, + { + "id": "b", + "text": "Flirty and dressed up" + }, + { + "id": "c", + "text": "Curious and new" + }, + { + "id": "d", + "text": "Quiet and unrushed" + } + ] } }, { "id": "date_night_006", "category_id": "date_night", - "type": "written", - "text": "What is one free date idea that actually sounds fun to you?", + "type": "single_choice", + "text": "Which date detail would make the night better?", "depth": 1, "access": "free", "tags": [ - "low_cost", - "fun" + "date_night", + "single_choice", + "details" + ], + "options": [ + { + "id": "a", + "text": "A reservation" + }, + { + "id": "b", + "text": "A good playlist" + }, + { + "id": "c", + "text": "A surprise dessert" + }, + { + "id": "d", + "text": "A place we can talk" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A reservation" + }, + { + "id": "b", + "text": "A good playlist" + }, + { + "id": "c", + "text": "A surprise dessert" + }, + { + "id": "d", + "text": "A place we can talk" + } + ] } }, { "id": "date_night_007", "category_id": "date_night", - "type": "written", - "text": "What kind of date helps you relax the fastest?", + "type": "single_choice", + "text": "What should we protect most on our next date?", "depth": 1, "access": "free", "tags": [ - "rest", - "preference" + "date_night", + "single_choice", + "priority" + ], + "options": [ + { + "id": "a", + "text": "No rushing" + }, + { + "id": "b", + "text": "Good food" + }, + { + "id": "c", + "text": "Real conversation" + }, + { + "id": "d", + "text": "A little flirting" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "No rushing" + }, + { + "id": "b", + "text": "Good food" + }, + { + "id": "c", + "text": "Real conversation" + }, + { + "id": "d", + "text": "A little flirting" + } + ] } }, { "id": "date_night_008", "category_id": "date_night", - "type": "written", - "text": "What is a tiny adventure we could do close to home?", + "type": "single_choice", + "text": "Which stay-in date would actually feel fun?", "depth": 1, "access": "free", "tags": [ - "adventure", - "low_cost" + "date_night", + "single_choice", + "stay_in" + ], + "options": [ + { + "id": "a", + "text": "Cooking something simple" + }, + { + "id": "b", + "text": "A movie with snacks" + }, + { + "id": "c", + "text": "A board game and dessert" + }, + { + "id": "d", + "text": "A music-and-drinks night" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Cooking something simple" + }, + { + "id": "b", + "text": "A movie with snacks" + }, + { + "id": "c", + "text": "A board game and dessert" + }, + { + "id": "d", + "text": "A music-and-drinks night" + } + ] } }, { "id": "date_night_009", "category_id": "date_night", - "type": "written", - "text": "What would make a walk together feel worth remembering?", + "type": "single_choice", + "text": "Which going-out date sounds easiest to say yes to?", "depth": 1, "access": "free", "tags": [ - "walk", - "memories" + "date_night", + "single_choice", + "going_out" + ], + "options": [ + { + "id": "a", + "text": "A favorite restaurant" + }, + { + "id": "b", + "text": "A new coffee shop" + }, + { + "id": "c", + "text": "A short walk downtown" + }, + { + "id": "d", + "text": "A bookstore stop" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A favorite restaurant" + }, + { + "id": "b", + "text": "A new coffee shop" + }, + { + "id": "c", + "text": "A short walk downtown" + }, + { + "id": "d", + "text": "A bookstore stop" + } + ] } }, { "id": "date_night_010", "category_id": "date_night", - "type": "written", - "text": "What is one thing we could do tonight to feel less bored?", + "type": "single_choice", + "text": "If date night starts late, what still works?", "depth": 1, "access": "free", "tags": [ - "tonight", - "fun" + "date_night", + "single_choice", + "late_night" + ], + "options": [ + { + "id": "a", + "text": "Dessert out" + }, + { + "id": "b", + "text": "A short drive" + }, + { + "id": "c", + "text": "A movie at home" + }, + { + "id": "d", + "text": "A quiet drink together" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Dessert out" + }, + { + "id": "b", + "text": "A short drive" + }, + { + "id": "c", + "text": "A movie at home" + }, + { + "id": "d", + "text": "A quiet drink together" + } + ] } }, { "id": "date_night_011", "category_id": "date_night", - "type": "written", - "text": "What is a date idea that would make you laugh?", + "type": "single_choice", + "text": "What would make a regular dinner feel special?", "depth": 1, "access": "free", "tags": [ - "playfulness", - "date_idea" + "date_night", + "single_choice", + "dinner" + ], + "options": [ + { + "id": "a", + "text": "Ordering something new" + }, + { + "id": "b", + "text": "Sitting somewhere nicer" + }, + { + "id": "c", + "text": "Dressing up a little" + }, + { + "id": "d", + "text": "Sharing dessert" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Ordering something new" + }, + { + "id": "b", + "text": "Sitting somewhere nicer" + }, + { + "id": "c", + "text": "Dressing up a little" + }, + { + "id": "d", + "text": "Sharing dessert" + } + ] } }, { "id": "date_night_012", "category_id": "date_night", - "type": "written", - "text": "What is one thing we could try just because it sounds fun?", + "type": "single_choice", + "text": "Which date would make us laugh without trying too hard?", "depth": 1, "access": "free", "tags": [ - "new_things", - "fun" + "date_night", + "single_choice", + "laugh" + ], + "options": [ + { + "id": "a", + "text": "A bad movie pick" + }, + { + "id": "b", + "text": "A mini golf round" + }, + { + "id": "c", + "text": "A thrift-store browse" + }, + { + "id": "d", + "text": "A cooking attempt" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A bad movie pick" + }, + { + "id": "b", + "text": "A mini golf round" + }, + { + "id": "c", + "text": "A thrift-store browse" + }, + { + "id": "d", + "text": "A cooking attempt" + } + ] } }, { "id": "date_night_013", "category_id": "date_night", - "type": "written", - "text": "What is a cozy date you would almost always say yes to?", + "type": "single_choice", + "text": "What date would feel worth leaving the house for?", "depth": 1, "access": "free", "tags": [ - "cozy", - "preference" + "date_night", + "single_choice", + "out" + ], + "options": [ + { + "id": "a", + "text": "Great food" + }, + { + "id": "b", + "text": "Live music" + }, + { + "id": "c", + "text": "A view" + }, + { + "id": "d", + "text": "A place we have not tried" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Great food" + }, + { + "id": "b", + "text": "Live music" + }, + { + "id": "c", + "text": "A view" + }, + { + "id": "d", + "text": "A place we have not tried" + } + ] } }, { "id": "date_night_014", "category_id": "date_night", - "type": "written", - "text": "What is a quick date we could fit into a busy week?", - "depth": 1, + "type": "single_choice", + "text": "Which date-night surprise would land best?", + "depth": 2, "access": "free", "tags": [ - "busy_life", - "quick_date" + "date_night", + "single_choice", + "surprise" + ], + "options": [ + { + "id": "a", + "text": "Dessert chosen for us" + }, + { + "id": "b", + "text": "A new spot picked ahead" + }, + { + "id": "c", + "text": "A playlist for the drive" + }, + { + "id": "d", + "text": "A small note before we go" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Dessert chosen for us" + }, + { + "id": "b", + "text": "A new spot picked ahead" + }, + { + "id": "c", + "text": "A playlist for the drive" + }, + { + "id": "d", + "text": "A small note before we go" + } + ] } }, { "id": "date_night_015", "category_id": "date_night", - "type": "written", - "text": "What would make dinner together feel like a date instead of a chore?", - "depth": 2, + "type": "single_choice", + "text": "What should our next at-home date include?", + "depth": 1, "access": "free", "tags": [ - "dinner", - "mindset" + "date_night", + "single_choice", + "home" + ], + "options": [ + { + "id": "a", + "text": "Something good to eat" + }, + { + "id": "b", + "text": "A movie we both picked" + }, + { + "id": "c", + "text": "A drink we actually like" + }, + { + "id": "d", + "text": "A start time we keep" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Something good to eat" + }, + { + "id": "b", + "text": "A movie we both picked" + }, + { + "id": "c", + "text": "A drink we actually like" + }, + { + "id": "d", + "text": "A start time we keep" + } + ] } }, { "id": "date_night_016", "category_id": "date_night", - "type": "written", - "text": "What is one place nearby you would like us to visit together?", - "depth": 1, + "type": "single_choice", + "text": "Which kind of date do we need more of?", + "depth": 2, "access": "free", "tags": [ - "going_out", - "local" + "date_night", + "single_choice", + "variety" + ], + "options": [ + { + "id": "a", + "text": "Slow and quiet" + }, + { + "id": "b", + "text": "Playful and active" + }, + { + "id": "c", + "text": "Dressed-up and romantic" + }, + { + "id": "d", + "text": "Simple and familiar" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Slow and quiet" + }, + { + "id": "b", + "text": "Playful and active" + }, + { + "id": "c", + "text": "Dressed-up and romantic" + }, + { + "id": "d", + "text": "Simple and familiar" + } + ] } }, { "id": "date_night_017", "category_id": "date_night", - "type": "written", - "text": "What kind of music would set the mood for a night in?", - "depth": 1, + "type": "single_choice", + "text": "What would make us both look forward to date night?", + "depth": 2, "access": "free", "tags": [ - "music", - "home_date" + "date_night", + "single_choice", + "anticipation" + ], + "options": [ + { + "id": "a", + "text": "A place we have been meaning to try" + }, + { + "id": "b", + "text": "A plan that is not too packed" + }, + { + "id": "c", + "text": "A reason to dress up" + }, + { + "id": "d", + "text": "A dessert we can split" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A place we have been meaning to try" + }, + { + "id": "b", + "text": "A plan that is not too packed" + }, + { + "id": "c", + "text": "A reason to dress up" + }, + { + "id": "d", + "text": "A dessert we can split" + } + ] } }, { "id": "date_night_018", "category_id": "date_night", - "type": "written", - "text": "What is a date we could do when we are tired but still want connection?", - "depth": 2, + "type": "single_choice", + "text": "Which date sounds best when we are both tired?", + "depth": 1, "access": "free", "tags": [ - "rest", - "connection" + "date_night", + "single_choice", + "tired" + ], + "options": [ + { + "id": "a", + "text": "Coffee and a walk" + }, + { + "id": "b", + "text": "Takeout with a movie" + }, + { + "id": "c", + "text": "A short dinner out" + }, + { + "id": "d", + "text": "Dessert and an early night" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Coffee and a walk" + }, + { + "id": "b", + "text": "Takeout with a movie" + }, + { + "id": "c", + "text": "A short dinner out" + }, + { + "id": "d", + "text": "Dessert and an early night" + } + ] } }, { "id": "date_night_019", "category_id": "date_night", - "type": "written", - "text": "What is something playful we could add to our next night together?", + "type": "single_choice", + "text": "What should we try before repeating our usual date?", "depth": 1, "access": "free", "tags": [ - "playfulness", - "date_night" + "date_night", + "single_choice", + "new" + ], + "options": [ + { + "id": "a", + "text": "A new appetizer" + }, + { + "id": "b", + "text": "A different neighborhood" + }, + { + "id": "c", + "text": "A matinee movie" + }, + { + "id": "d", + "text": "A local event" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A new appetizer" + }, + { + "id": "b", + "text": "A different neighborhood" + }, + { + "id": "c", + "text": "A matinee movie" + }, + { + "id": "d", + "text": "A local event" + } + ] } }, { "id": "date_night_020", "category_id": "date_night", - "type": "written", - "text": "What is a small surprise that would make you smile on a date?", + "type": "single_choice", + "text": "Which date feels most like our style?", "depth": 2, "access": "free", "tags": [ - "surprise", - "thoughtful" + "date_night", + "single_choice", + "style" + ], + "options": [ + { + "id": "a", + "text": "Comfortable and familiar" + }, + { + "id": "b", + "text": "A little spontaneous" + }, + { + "id": "c", + "text": "Quiet but romantic" + }, + { + "id": "d", + "text": "Playful and low-pressure" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Comfortable and familiar" + }, + { + "id": "b", + "text": "A little spontaneous" + }, + { + "id": "c", + "text": "Quiet but romantic" + }, + { + "id": "d", + "text": "Playful and low-pressure" + } + ] } }, { "id": "date_night_021", "category_id": "date_night", - "type": "written", - "text": "What is your ideal lazy date with me?", - "depth": 1, + "type": "single_choice", + "text": "What date-night move would feel most romantic?", + "depth": 2, "access": "free", "tags": [ - "rest", - "preference" + "date_night", + "single_choice", + "romance" + ], + "options": [ + { + "id": "a", + "text": "Saving time to talk" + }, + { + "id": "b", + "text": "Choosing a thoughtful spot" + }, + { + "id": "c", + "text": "Holding hands more" + }, + { + "id": "d", + "text": "Ending with dessert" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Saving time to talk" + }, + { + "id": "b", + "text": "Choosing a thoughtful spot" + }, + { + "id": "c", + "text": "Holding hands more" + }, + { + "id": "d", + "text": "Ending with dessert" + } + ] } }, { "id": "date_night_022", "category_id": "date_night", - "type": "written", - "text": "What is one meal that feels like a date-night meal to you?", + "type": "single_choice", + "text": "Which small splurge feels worth it?", "depth": 1, "access": "free", "tags": [ - "food", - "dinner" + "date_night", + "single_choice", + "splurge" + ], + "options": [ + { + "id": "a", + "text": "A nicer dessert" + }, + { + "id": "b", + "text": "Better seats" + }, + { + "id": "c", + "text": "A ride instead of parking stress" + }, + { + "id": "d", + "text": "A drink somewhere pretty" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A nicer dessert" + }, + { + "id": "b", + "text": "Better seats" + }, + { + "id": "c", + "text": "A ride instead of parking stress" + }, + { + "id": "d", + "text": "A drink somewhere pretty" + } + ] } }, { "id": "date_night_023", "category_id": "date_night", - "type": "written", - "text": "What would make breakfast or coffee together feel like a real date?", + "type": "single_choice", + "text": "What would make the next date easier to start?", "depth": 1, "access": "free", "tags": [ - "coffee_date", - "morning" + "date_night", + "single_choice", + "start" + ], + "options": [ + { + "id": "a", + "text": "Picking the place now" + }, + { + "id": "b", + "text": "Choosing the time now" + }, + { + "id": "c", + "text": "Keeping it close to home" + }, + { + "id": "d", + "text": "Making it casual" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Picking the place now" + }, + { + "id": "b", + "text": "Choosing the time now" + }, + { + "id": "c", + "text": "Keeping it close to home" + }, + { + "id": "d", + "text": "Making it casual" + } + ] } }, { "id": "date_night_024", "category_id": "date_night", - "type": "written", - "text": "What is a date we could do without spending money?", - "depth": 1, + "type": "single_choice", + "text": "Which date would be fun to repeat?", + "depth": 2, "access": "free", "tags": [ - "low_cost", - "free" + "date_night", + "single_choice", + "repeat" + ], + "options": [ + { + "id": "a", + "text": "Our first-date style" + }, + { + "id": "b", + "text": "Our favorite dinner spot" + }, + { + "id": "c", + "text": "A walk we always like" + }, + { + "id": "d", + "text": "A movie night that worked" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Our first-date style" + }, + { + "id": "b", + "text": "Our favorite dinner spot" + }, + { + "id": "c", + "text": "A walk we always like" + }, + { + "id": "d", + "text": "A movie night that worked" + } + ] } }, { "id": "date_night_025", "category_id": "date_night", - "type": "written", - "text": "What would make a car ride together feel fun?", - "depth": 1, + "type": "single_choice", + "text": "What kind of date makes us talk the most?", + "depth": 2, "access": "free", "tags": [ - "drive", - "fun" + "date_night", + "single_choice", + "conversation" + ], + "options": [ + { + "id": "a", + "text": "A long walk" + }, + { + "id": "b", + "text": "A quiet restaurant" + }, + { + "id": "c", + "text": "A scenic drive" + }, + { + "id": "d", + "text": "Coffee with nowhere to rush" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A long walk" + }, + { + "id": "b", + "text": "A quiet restaurant" + }, + { + "id": "c", + "text": "A scenic drive" + }, + { + "id": "d", + "text": "Coffee with nowhere to rush" + } + ] } }, { "id": "date_night_026", "category_id": "date_night", - "type": "written", - "text": "What is a simple outdoor date you would enjoy?", + "type": "single_choice", + "text": "Which date should we save for a good-weather day?", "depth": 1, "access": "free", "tags": [ - "outside", - "date_idea" + "date_night", + "single_choice", + "weather" + ], + "options": [ + { + "id": "a", + "text": "A picnic" + }, + { + "id": "b", + "text": "A long walk" + }, + { + "id": "c", + "text": "Outdoor music" + }, + { + "id": "d", + "text": "A patio dinner" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A picnic" + }, + { + "id": "b", + "text": "A long walk" + }, + { + "id": "c", + "text": "Outdoor music" + }, + { + "id": "d", + "text": "A patio dinner" + } + ] } }, { "id": "date_night_027", "category_id": "date_night", - "type": "written", - "text": "What is a rainy-day date we should keep in our back pocket?", + "type": "single_choice", + "text": "What date would make an ordinary week feel better?", "depth": 1, "access": "free", "tags": [ - "rainy_day", - "home_date" + "date_night", + "single_choice", + "ordinary_week" + ], + "options": [ + { + "id": "a", + "text": "A midweek dinner" + }, + { + "id": "b", + "text": "A dessert run" + }, + { + "id": "c", + "text": "A planned movie night" + }, + { + "id": "d", + "text": "A coffee date before errands" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A midweek dinner" + }, + { + "id": "b", + "text": "A dessert run" + }, + { + "id": "c", + "text": "A planned movie night" + }, + { + "id": "d", + "text": "A coffee date before errands" + } + ] } }, { "id": "date_night_028", "category_id": "date_night", - "type": "written", - "text": "What would make a regular grocery trip feel more like us?", - "depth": 1, + "type": "single_choice", + "text": "Which date feels most worth planning ahead?", + "depth": 2, "access": "free", "tags": [ - "errands", - "playfulness" + "date_night", + "single_choice", + "plan_ahead" + ], + "options": [ + { + "id": "a", + "text": "A new restaurant" + }, + { + "id": "b", + "text": "A day trip" + }, + { + "id": "c", + "text": "A show" + }, + { + "id": "d", + "text": "A dressed-up dinner" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A new restaurant" + }, + { + "id": "b", + "text": "A day trip" + }, + { + "id": "c", + "text": "A show" + }, + { + "id": "d", + "text": "A dressed-up dinner" + } + ] } }, { "id": "date_night_029", "category_id": "date_night", - "type": "written", - "text": "What is one thing we could cook together that would be fun?", + "type": "single_choice", + "text": "What would make a spontaneous date actually work?", "depth": 1, "access": "free", "tags": [ - "cooking", - "food" + "date_night", + "single_choice", + "spontaneous" + ], + "options": [ + { + "id": "a", + "text": "Keeping it close" + }, + { + "id": "b", + "text": "Choosing one clear plan" + }, + { + "id": "c", + "text": "Leaving room to wander" + }, + { + "id": "d", + "text": "Having food first" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Keeping it close" + }, + { + "id": "b", + "text": "Choosing one clear plan" + }, + { + "id": "c", + "text": "Leaving room to wander" + }, + { + "id": "d", + "text": "Having food first" + } + ] } }, { "id": "date_night_030", "category_id": "date_night", - "type": "written", - "text": "What would make a game night feel more like a date?", - "depth": 1, + "type": "single_choice", + "text": "Which date-night rule would help us enjoy it more?", + "depth": 2, "access": "free", "tags": [ - "game_night", - "home_date" + "date_night", + "single_choice", + "rule" + ], + "options": [ + { + "id": "a", + "text": "No rushing the end" + }, + { + "id": "b", + "text": "No planning during the date" + }, + { + "id": "c", + "text": "Try one new thing" + }, + { + "id": "d", + "text": "Save room for dessert" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "No rushing the end" + }, + { + "id": "b", + "text": "No planning during the date" + }, + { + "id": "c", + "text": "Try one new thing" + }, + { + "id": "d", + "text": "Save room for dessert" + } + ] } }, { "id": "date_night_031", "category_id": "date_night", - "type": "written", - "text": "What is a date idea that feels easy on the budget and still sweet?", - "depth": 1, + "type": "single_choice", + "text": "What date would feel most like a reset from the week?", + "depth": 2, "access": "free", "tags": [ - "budget", - "sweet" + "date_night", + "single_choice", + "week" + ], + "options": [ + { + "id": "a", + "text": "Dinner somewhere calm" + }, + { + "id": "b", + "text": "A walk near water" + }, + { + "id": "c", + "text": "A cozy night in" + }, + { + "id": "d", + "text": "A slow brunch" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Dinner somewhere calm" + }, + { + "id": "b", + "text": "A walk near water" + }, + { + "id": "c", + "text": "A cozy night in" + }, + { + "id": "d", + "text": "A slow brunch" + } + ] } }, { "id": "date_night_032", "category_id": "date_night", - "type": "written", - "text": "What would make our next at-home date feel intentional?", - "depth": 2, + "type": "single_choice", + "text": "Which date sounds best with no big production?", + "depth": 1, "access": "free", "tags": [ - "home_date", - "intentional" + "date_night", + "single_choice", + "simple" + ], + "options": [ + { + "id": "a", + "text": "A favorite takeout order" + }, + { + "id": "b", + "text": "A couch movie picked together" + }, + { + "id": "c", + "text": "A coffee shop visit" + }, + { + "id": "d", + "text": "A sunset walk" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A favorite takeout order" + }, + { + "id": "b", + "text": "A couch movie picked together" + }, + { + "id": "c", + "text": "A coffee shop visit" + }, + { + "id": "d", + "text": "A sunset walk" + } + ] } }, { "id": "date_night_033", "category_id": "date_night", - "type": "written", - "text": "What is one little detail that makes a date feel planned with care?", + "type": "single_choice", + "text": "What should we pick if the goal is chemistry?", "depth": 2, "access": "free", "tags": [ - "thoughtful", - "planning" + "date_night", + "single_choice", + "flirty" + ], + "options": [ + { + "id": "a", + "text": "A dressed-up dinner" + }, + { + "id": "b", + "text": "A slow dance at home" + }, + { + "id": "c", + "text": "A flirtier text before we meet" + }, + { + "id": "d", + "text": "A quiet corner booth" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A dressed-up dinner" + }, + { + "id": "b", + "text": "A slow dance at home" + }, + { + "id": "c", + "text": "A flirtier text before we meet" + }, + { + "id": "d", + "text": "A quiet corner booth" + } + ] } }, { "id": "date_night_034", "category_id": "date_night", - "type": "written", - "text": "What helps you enjoy a date even when the plan is simple?", + "type": "single_choice", + "text": "Which date would make us feel more like us?", "depth": 2, "access": "free", "tags": [ - "simple_dates", - "enjoyment" + "date_night", + "single_choice", + "us" + ], + "options": [ + { + "id": "a", + "text": "Our favorite food" + }, + { + "id": "b", + "text": "A place with memories" + }, + { + "id": "c", + "text": "A night with music" + }, + { + "id": "d", + "text": "Something easy and funny" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Our favorite food" + }, + { + "id": "b", + "text": "A place with memories" + }, + { + "id": "c", + "text": "A night with music" + }, + { + "id": "d", + "text": "Something easy and funny" + } + ] } }, { "id": "date_night_035", "category_id": "date_night", - "type": "written", - "text": "What is one date we could do in under an hour?", + "type": "single_choice", + "text": "What should our next date have more of?", "depth": 1, "access": "free", "tags": [ - "quick_date", - "busy_life" + "date_night", + "single_choice", + "more_of" + ], + "options": [ + { + "id": "a", + "text": "Time to talk" + }, + { + "id": "b", + "text": "Something new" + }, + { + "id": "c", + "text": "A little romance" + }, + { + "id": "d", + "text": "A reason to laugh" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Time to talk" + }, + { + "id": "b", + "text": "Something new" + }, + { + "id": "c", + "text": "A little romance" + }, + { + "id": "d", + "text": "A reason to laugh" + } + ] } }, { "id": "date_night_036", "category_id": "date_night", - "type": "written", - "text": "What is a date we could do after a long day?", + "type": "single_choice", + "text": "Which date sounds best on a budget?", "depth": 1, "access": "free", "tags": [ - "after_work", - "rest" + "date_night", + "single_choice", + "budget" + ], + "options": [ + { + "id": "a", + "text": "Homemade dessert night" + }, + { + "id": "b", + "text": "A coffee walk" + }, + { + "id": "c", + "text": "A free local event" + }, + { + "id": "d", + "text": "A picnic with favorites" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Homemade dessert night" + }, + { + "id": "b", + "text": "A coffee walk" + }, + { + "id": "c", + "text": "A free local event" + }, + { + "id": "d", + "text": "A picnic with favorites" + } + ] } }, { "id": "date_night_037", "category_id": "date_night", - "type": "written", - "text": "What would make takeout at home feel less ordinary?", - "depth": 1, + "type": "single_choice", + "text": "What would make a date feel thoughtful without overdoing it?", + "depth": 2, "access": "free", "tags": [ - "takeout", - "home_date" + "date_night", + "single_choice", + "thoughtful" + ], + "options": [ + { + "id": "a", + "text": "A place chosen for us" + }, + { + "id": "b", + "text": "A song on the way" + }, + { + "id": "c", + "text": "A dessert remembered" + }, + { + "id": "d", + "text": "A photo before we leave" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A place chosen for us" + }, + { + "id": "b", + "text": "A song on the way" + }, + { + "id": "c", + "text": "A dessert remembered" + }, + { + "id": "d", + "text": "A photo before we leave" + } + ] } }, { "id": "date_night_038", "category_id": "date_night", - "type": "written", - "text": "What is a dessert-only date you would enjoy?", + "type": "single_choice", + "text": "Which date should we do when we need a win?", "depth": 1, "access": "free", "tags": [ - "dessert", - "food" + "date_night", + "single_choice", + "easy_win" + ], + "options": [ + { + "id": "a", + "text": "A sure-thing restaurant" + }, + { + "id": "b", + "text": "A comfort movie night" + }, + { + "id": "c", + "text": "A short walk and dessert" + }, + { + "id": "d", + "text": "A breakfast date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A sure-thing restaurant" + }, + { + "id": "b", + "text": "A comfort movie night" + }, + { + "id": "c", + "text": "A short walk and dessert" + }, + { + "id": "d", + "text": "A breakfast date" + } + ] } }, { "id": "date_night_039", "category_id": "date_night", - "type": "written", - "text": "What is a date we could do in comfortable clothes?", - "depth": 1, + "type": "single_choice", + "text": "What kind of date do we keep putting off?", + "depth": 2, "access": "free", "tags": [ - "cozy", - "comfort" + "date_night", + "single_choice", + "future" + ], + "options": [ + { + "id": "a", + "text": "A day trip" + }, + { + "id": "b", + "text": "A fancy dinner" + }, + { + "id": "c", + "text": "A museum or exhibit" + }, + { + "id": "d", + "text": "A new neighborhood walk" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A day trip" + }, + { + "id": "b", + "text": "A fancy dinner" + }, + { + "id": "c", + "text": "A museum or exhibit" + }, + { + "id": "d", + "text": "A new neighborhood walk" + } + ] } }, { "id": "date_night_040", "category_id": "date_night", - "type": "written", - "text": "What is one way to make our next date feel playful from the start?", + "type": "single_choice", + "text": "Which date-night ending sounds best?", "depth": 2, "access": "free", "tags": [ - "playfulness", - "start" + "date_night", + "single_choice", + "ending" + ], + "options": [ + { + "id": "a", + "text": "Dessert split slowly" + }, + { + "id": "b", + "text": "A walk before home" + }, + { + "id": "c", + "text": "A movie after dinner" + }, + { + "id": "d", + "text": "A long kiss goodnight" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Dessert split slowly" + }, + { + "id": "b", + "text": "A walk before home" + }, + { + "id": "c", + "text": "A movie after dinner" + }, + { + "id": "d", + "text": "A long kiss goodnight" + } + ] } }, { "id": "date_night_041", "category_id": "date_night", - "type": "written", - "text": "What kind of date makes you feel most like yourself with me?", - "depth": 2, + "type": "single_choice", + "text": "What would make the next date feel less routine?", + "depth": 1, "access": "free", "tags": [ - "comfort", - "identity" + "date_night", + "single_choice", + "routine" + ], + "options": [ + { + "id": "a", + "text": "A different part of town" + }, + { + "id": "b", + "text": "A surprise stop" + }, + { + "id": "c", + "text": "A new outfit" + }, + { + "id": "d", + "text": "A new dish to share" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A different part of town" + }, + { + "id": "b", + "text": "A surprise stop" + }, + { + "id": "c", + "text": "A new outfit" + }, + { + "id": "d", + "text": "A new dish to share" + } + ] } }, { "id": "date_night_042", "category_id": "date_night", - "type": "written", - "text": "What is one date idea that feels like us?", + "type": "single_choice", + "text": "Which date would make a good memory?", "depth": 2, "access": "free", "tags": [ - "couple_identity", - "date_idea" + "date_night", + "single_choice", + "memory" + ], + "options": [ + { + "id": "a", + "text": "A place with a view" + }, + { + "id": "b", + "text": "A day trip with photos" + }, + { + "id": "c", + "text": "A dinner where we dress up" + }, + { + "id": "d", + "text": "A silly activity we can laugh about" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A place with a view" + }, + { + "id": "b", + "text": "A day trip with photos" + }, + { + "id": "c", + "text": "A dinner where we dress up" + }, + { + "id": "d", + "text": "A silly activity we can laugh about" + } + ] } }, { "id": "date_night_043", "category_id": "date_night", - "type": "written", - "text": "What is a place where you would like to sit and talk with me?", - "depth": 1, + "type": "single_choice", + "text": "What should we choose when we want easy romance?", + "depth": 2, "access": "free", "tags": [ - "conversation", - "location" + "date_night", + "single_choice", + "easy_romance" + ], + "options": [ + { + "id": "a", + "text": "A quiet table" + }, + { + "id": "b", + "text": "A slow song at home" + }, + { + "id": "c", + "text": "A dessert walk" + }, + { + "id": "d", + "text": "A note before the date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A quiet table" + }, + { + "id": "b", + "text": "A slow song at home" + }, + { + "id": "c", + "text": "A dessert walk" + }, + { + "id": "d", + "text": "A note before the date" + } + ] } }, { "id": "date_night_044", "category_id": "date_night", - "type": "written", - "text": "What is a date we should try during the next nice-weather day?", + "type": "single_choice", + "text": "Which date feels most like a treat?", "depth": 1, "access": "free", "tags": [ - "weather", - "outside" + "date_night", + "single_choice", + "treat" + ], + "options": [ + { + "id": "a", + "text": "Brunch somewhere good" + }, + { + "id": "b", + "text": "A movie with the good seats" + }, + { + "id": "c", + "text": "A dessert place we love" + }, + { + "id": "d", + "text": "A little weekend drive" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Brunch somewhere good" + }, + { + "id": "b", + "text": "A movie with the good seats" + }, + { + "id": "c", + "text": "A dessert place we love" + }, + { + "id": "d", + "text": "A little weekend drive" + } + ] } }, { "id": "date_night_045", "category_id": "date_night", - "type": "written", - "text": "What is one seasonal date you want us to do this year?", + "type": "single_choice", + "text": "What would make planning date night less annoying?", "depth": 1, "access": "free", "tags": [ - "seasonal", - "date_idea" + "date_night", + "single_choice", + "planning" + ], + "options": [ + { + "id": "a", + "text": "Two options and a pick" + }, + { + "id": "b", + "text": "A saved list of places" + }, + { + "id": "c", + "text": "Taking turns planning" + }, + { + "id": "d", + "text": "Keeping one backup idea" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Two options and a pick" + }, + { + "id": "b", + "text": "A saved list of places" + }, + { + "id": "c", + "text": "Taking turns planning" + }, + { + "id": "d", + "text": "Keeping one backup idea" + } + ] } }, { "id": "date_night_046", "category_id": "date_night", - "type": "written", - "text": "What would make a picnic feel worth the effort?", + "type": "single_choice", + "text": "Which date should we keep in our back pocket?", "depth": 1, "access": "free", "tags": [ - "picnic", - "planning" + "date_night", + "single_choice", + "backup" + ], + "options": [ + { + "id": "a", + "text": "Coffee and a walk" + }, + { + "id": "b", + "text": "Takeout and a movie" + }, + { + "id": "c", + "text": "Dessert after dinner" + }, + { + "id": "d", + "text": "A bookstore wander" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Coffee and a walk" + }, + { + "id": "b", + "text": "Takeout and a movie" + }, + { + "id": "c", + "text": "Dessert after dinner" + }, + { + "id": "d", + "text": "A bookstore wander" + } + ] } }, { "id": "date_night_047", "category_id": "date_night", - "type": "written", - "text": "What is an errand we could turn into a mini date?", + "type": "single_choice", + "text": "What date would feel best after a long week?", "depth": 1, "access": "free", "tags": [ - "errands", - "mini_date" + "date_night", + "single_choice", + "long_week" + ], + "options": [ + { + "id": "a", + "text": "A calm dinner" + }, + { + "id": "b", + "text": "A movie we do not have to explain" + }, + { + "id": "c", + "text": "A slow morning brunch" + }, + { + "id": "d", + "text": "A short drive with music" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A calm dinner" + }, + { + "id": "b", + "text": "A movie we do not have to explain" + }, + { + "id": "c", + "text": "A slow morning brunch" + }, + { + "id": "d", + "text": "A short drive with music" + } + ] } }, { "id": "date_night_048", "category_id": "date_night", - "type": "written", - "text": "What is a small local place we should explore together?", - "depth": 1, + "type": "single_choice", + "text": "Which date makes room for flirting?", + "depth": 2, "access": "free", "tags": [ - "local", - "adventure" + "date_night", + "single_choice", + "flirt" + ], + "options": [ + { + "id": "a", + "text": "A corner booth" + }, + { + "id": "b", + "text": "A dressed-up night" + }, + { + "id": "c", + "text": "A walk after dessert" + }, + { + "id": "d", + "text": "A stay-in dinner with music" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A corner booth" + }, + { + "id": "b", + "text": "A dressed-up night" + }, + { + "id": "c", + "text": "A walk after dessert" + }, + { + "id": "d", + "text": "A stay-in dinner with music" + } + ] } }, { "id": "date_night_049", "category_id": "date_night", - "type": "written", - "text": "What is one date idea that would get us out of our usual routine?", - "depth": 2, + "type": "single_choice", + "text": "What would make a familiar date feel new again?", + "depth": 1, "access": "free", "tags": [ - "rut_breaking", - "new_things" + "date_night", + "single_choice", + "fresh" + ], + "options": [ + { + "id": "a", + "text": "Changing the route" + }, + { + "id": "b", + "text": "Ordering differently" + }, + { + "id": "c", + "text": "Dressing up for it" + }, + { + "id": "d", + "text": "Adding one surprise stop" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Changing the route" + }, + { + "id": "b", + "text": "Ordering differently" + }, + { + "id": "c", + "text": "Dressing up for it" + }, + { + "id": "d", + "text": "Adding one surprise stop" + } + ] } }, { "id": "date_night_050", "category_id": "date_night", - "type": "written", - "text": "What would make trying something new feel safe and fun for you?", - "depth": 2, + "type": "single_choice", + "text": "Which next-date idea should we actually put on the calendar?", + "depth": 1, "access": "free", "tags": [ - "new_things", - "comfort" + "date_night", + "single_choice", + "calendar" + ], + "options": [ + { + "id": "a", + "text": "Dinner somewhere new" + }, + { + "id": "b", + "text": "A walk with coffee" + }, + { + "id": "c", + "text": "A stay-in dinner plan" + }, + { + "id": "d", + "text": "A local event this month" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Dinner somewhere new" + }, + { + "id": "b", + "text": "A walk with coffee" + }, + { + "id": "c", + "text": "A stay-in dinner plan" + }, + { + "id": "d", + "text": "A local event this month" + } + ] } }, { "id": "date_night_051", "category_id": "date_night", - "type": "written", - "text": "What is a date we could do with no phones?", - "depth": 2, + "type": "multi_choice", + "text": "Pick anything that would make a stay-in date feel intentional:", + "depth": 1, "access": "free", "tags": [ - "phones", - "presence" + "date_night", + "multi_choice", + "stay_in" + ], + "options": [ + { + "id": "a", + "text": "A real start time" + }, + { + "id": "b", + "text": "A dinner we both chose" + }, + { + "id": "c", + "text": "Phones out of reach" + }, + { + "id": "d", + "text": "A movie picked before we sit down" + }, + { + "id": "e", + "text": "Dessert saved for later" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A real start time" + }, + { + "id": "b", + "text": "A dinner we both chose" + }, + { + "id": "c", + "text": "Phones out of reach" + }, + { + "id": "d", + "text": "A movie picked before we sit down" + }, + { + "id": "e", + "text": "Dessert saved for later" + } + ] } }, { "id": "date_night_052", "category_id": "date_night", - "type": "written", - "text": "What is a date that would help us slow down together?", - "depth": 2, + "type": "multi_choice", + "text": "Choose the stay-in details that sound worth doing:", + "depth": 1, "access": "free", "tags": [ - "slow_date", - "rest" + "date_night", + "multi_choice", + "stay_in" + ], + "options": [ + { + "id": "a", + "text": "A movie picked before we sit down" + }, + { + "id": "b", + "text": "A playlist in the background" + }, + { + "id": "c", + "text": "Phones out of reach" + }, + { + "id": "d", + "text": "A drink we both like" + }, + { + "id": "e", + "text": "Dessert saved for later" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A movie picked before we sit down" + }, + { + "id": "b", + "text": "A playlist in the background" + }, + { + "id": "c", + "text": "Phones out of reach" + }, + { + "id": "d", + "text": "A drink we both like" + }, + { + "id": "e", + "text": "Dessert saved for later" + } + ] } }, { "id": "date_night_053", "category_id": "date_night", - "type": "written", - "text": "What kind of date makes conversation come easily for you?", - "depth": 2, + "type": "multi_choice", + "text": "What should we add so home feels like date night?", + "depth": 1, "access": "free", "tags": [ - "conversation", - "preference" + "date_night", + "multi_choice", + "stay_in" + ], + "options": [ + { + "id": "a", + "text": "Dessert saved for later" + }, + { + "id": "b", + "text": "A playlist in the background" + }, + { + "id": "c", + "text": "A drink we both like" + }, + { + "id": "d", + "text": "A photo before the night ends" + }, + { + "id": "e", + "text": "A real start time" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Dessert saved for later" + }, + { + "id": "b", + "text": "A playlist in the background" + }, + { + "id": "c", + "text": "A drink we both like" + }, + { + "id": "d", + "text": "A photo before the night ends" + }, + { + "id": "e", + "text": "A real start time" + } + ] } }, { "id": "date_night_054", "category_id": "date_night", - "type": "written", - "text": "What is one question you would like me to ask on a date?", - "depth": 2, + "type": "multi_choice", + "text": "Select the touches that make staying in feel planned:", + "depth": 1, "access": "free", "tags": [ - "conversation", - "curiosity" + "date_night", + "multi_choice", + "stay_in" + ], + "options": [ + { + "id": "a", + "text": "A photo before the night ends" + }, + { + "id": "b", + "text": "A dinner we both chose" + }, + { + "id": "c", + "text": "A drink we both like" + }, + { + "id": "d", + "text": "Phones out of reach" + }, + { + "id": "e", + "text": "A real start time" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A photo before the night ends" + }, + { + "id": "b", + "text": "A dinner we both chose" + }, + { + "id": "c", + "text": "A drink we both like" + }, + { + "id": "d", + "text": "Phones out of reach" + }, + { + "id": "e", + "text": "A real start time" + } + ] } }, { "id": "date_night_055", "category_id": "date_night", - "type": "written", - "text": "What topic should we save for date night instead of rushing through?", - "depth": 2, + "type": "multi_choice", + "text": "Which home-date ideas actually sound good?", + "depth": 1, "access": "free", "tags": [ - "conversation", - "timing" + "date_night", + "multi_choice", + "stay_in" + ], + "options": [ + { + "id": "a", + "text": "A real start time for this date" + }, + { + "id": "b", + "text": "A dinner we both chose" + }, + { + "id": "c", + "text": "Phones out of reach for this date" + }, + { + "id": "d", + "text": "A movie picked before we sit down" + }, + { + "id": "e", + "text": "Dessert saved for later for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A real start time for this date" + }, + { + "id": "b", + "text": "A dinner we both chose" + }, + { + "id": "c", + "text": "Phones out of reach for this date" + }, + { + "id": "d", + "text": "A movie picked before we sit down" + }, + { + "id": "e", + "text": "Dessert saved for later for this date" + } + ] } }, { "id": "date_night_056", "category_id": "date_night", - "type": "written", - "text": "What topic should we avoid if we want the date to stay light?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "Pick the parts of going out that would make the date better:", + "depth": 1, + "access": "free", "tags": [ - "boundaries", - "topics" + "date_night", + "multi_choice", + "going_out" + ], + "options": [ + { + "id": "a", + "text": "A table where we can talk" + }, + { + "id": "b", + "text": "A place with good lighting" + }, + { + "id": "c", + "text": "One new thing to share" + }, + { + "id": "d", + "text": "Time for a walk after" + }, + { + "id": "e", + "text": "No packed schedule" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A table where we can talk" + }, + { + "id": "b", + "text": "A place with good lighting" + }, + { + "id": "c", + "text": "One new thing to share" + }, + { + "id": "d", + "text": "Time for a walk after" + }, + { + "id": "e", + "text": "No packed schedule" + } + ] } }, { "id": "date_night_057", "category_id": "date_night", - "type": "written", - "text": "What makes you feel like I am really present with you?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "Choose what makes leaving the house worth it:", + "depth": 1, + "access": "free", "tags": [ - "presence", - "attention" + "date_night", + "multi_choice", + "going_out" + ], + "options": [ + { + "id": "a", + "text": "Time for a walk after" + }, + { + "id": "b", + "text": "Dessert somewhere else" + }, + { + "id": "c", + "text": "One new thing to share" + }, + { + "id": "d", + "text": "A reason to dress up" + }, + { + "id": "e", + "text": "No packed schedule" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Time for a walk after" + }, + { + "id": "b", + "text": "Dessert somewhere else" + }, + { + "id": "c", + "text": "One new thing to share" + }, + { + "id": "d", + "text": "A reason to dress up" + }, + { + "id": "e", + "text": "No packed schedule" + } + ] } }, { "id": "date_night_058", "category_id": "date_night", - "type": "written", - "text": "What helps you stay present with me during a date?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "Which going-out details matter most to us?", + "depth": 1, + "access": "free", "tags": [ - "presence", - "support" + "date_night", + "multi_choice", + "going_out" + ], + "options": [ + { + "id": "a", + "text": "No packed schedule" + }, + { + "id": "b", + "text": "Dessert somewhere else" + }, + { + "id": "c", + "text": "A reason to dress up" + }, + { + "id": "d", + "text": "A reservation that removes guessing" + }, + { + "id": "e", + "text": "A table where we can talk" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "No packed schedule" + }, + { + "id": "b", + "text": "Dessert somewhere else" + }, + { + "id": "c", + "text": "A reason to dress up" + }, + { + "id": "d", + "text": "A reservation that removes guessing" + }, + { + "id": "e", + "text": "A table where we can talk" + } + ] } }, { "id": "date_night_059", "category_id": "date_night", - "type": "written", - "text": "What is one thing that usually distracts us from enjoying time together?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "What should our next night out include?", + "depth": 1, + "access": "free", "tags": [ - "distractions", - "awareness" + "date_night", + "multi_choice", + "going_out" + ], + "options": [ + { + "id": "a", + "text": "A reservation that removes guessing" + }, + { + "id": "b", + "text": "A place with good lighting" + }, + { + "id": "c", + "text": "A reason to dress up for this date" + }, + { + "id": "d", + "text": "One new thing to share" + }, + { + "id": "e", + "text": "A table where we can talk" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A reservation that removes guessing" + }, + { + "id": "b", + "text": "A place with good lighting" + }, + { + "id": "c", + "text": "A reason to dress up for this date" + }, + { + "id": "d", + "text": "One new thing to share" + }, + { + "id": "e", + "text": "A table where we can talk" + } + ] } }, { "id": "date_night_060", "category_id": "date_night", - "type": "written", - "text": "What would make our next date feel calmer?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "Select the pieces that make a simple night out feel good:", + "depth": 1, + "access": "free", "tags": [ - "calm", - "date_night" + "date_night", + "multi_choice", + "going_out" + ], + "options": [ + { + "id": "a", + "text": "A table where we can talk for this date" + }, + { + "id": "b", + "text": "A place with good lighting" + }, + { + "id": "c", + "text": "One new thing to share for this date" + }, + { + "id": "d", + "text": "Time for a walk after" + }, + { + "id": "e", + "text": "No packed schedule for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A table where we can talk for this date" + }, + { + "id": "b", + "text": "A place with good lighting" + }, + { + "id": "c", + "text": "One new thing to share for this date" + }, + { + "id": "d", + "text": "Time for a walk after" + }, + { + "id": "e", + "text": "No packed schedule for this date" + } + ] } }, { "id": "date_night_061", "category_id": "date_night", - "type": "written", - "text": "What is one thing that would make date planning easier for you?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "Pick the dinner-date moves that sound good:", + "depth": 1, + "access": "free", "tags": [ - "planning", - "ease" + "date_night", + "multi_choice", + "dinner" + ], + "options": [ + { + "id": "a", + "text": "A shared appetizer" + }, + { + "id": "b", + "text": "A corner table" + }, + { + "id": "c", + "text": "A dessert we split" + }, + { + "id": "d", + "text": "Ordering something new" + }, + { + "id": "e", + "text": "A toast before eating" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A shared appetizer" + }, + { + "id": "b", + "text": "A corner table" + }, + { + "id": "c", + "text": "A dessert we split" + }, + { + "id": "d", + "text": "Ordering something new" + }, + { + "id": "e", + "text": "A toast before eating" + } + ] } }, { "id": "date_night_062", "category_id": "date_night", - "type": "written", - "text": "How much notice helps you actually look forward to a date?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "Which dinner details would make the night feel special?", + "depth": 1, + "access": "free", "tags": [ - "planning", - "notice" + "date_night", + "multi_choice", + "dinner" + ], + "options": [ + { + "id": "a", + "text": "Ordering something new" + }, + { + "id": "b", + "text": "A slow walk after" + }, + { + "id": "c", + "text": "A dessert we split" + }, + { + "id": "d", + "text": "No phones on the table" + }, + { + "id": "e", + "text": "A toast before eating" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Ordering something new" + }, + { + "id": "b", + "text": "A slow walk after" + }, + { + "id": "c", + "text": "A dessert we split" + }, + { + "id": "d", + "text": "No phones on the table" + }, + { + "id": "e", + "text": "A toast before eating" + } + ] } }, { "id": "date_night_063", "category_id": "date_night", - "type": "written", - "text": "What kind of plan feels romantic without feeling stressful?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "What should we include in our next dinner date?", + "depth": 1, + "access": "free", "tags": [ - "romance", - "planning" + "date_night", + "multi_choice", + "dinner" + ], + "options": [ + { + "id": "a", + "text": "A toast before eating" + }, + { + "id": "b", + "text": "A slow walk after" + }, + { + "id": "c", + "text": "No phones on the table" + }, + { + "id": "d", + "text": "A place neither of us has to defend" + }, + { + "id": "e", + "text": "A shared appetizer" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A toast before eating" + }, + { + "id": "b", + "text": "A slow walk after" + }, + { + "id": "c", + "text": "No phones on the table" + }, + { + "id": "d", + "text": "A place neither of us has to defend" + }, + { + "id": "e", + "text": "A shared appetizer" + } + ] } }, { "id": "date_night_064", "category_id": "date_night", - "type": "written", - "text": "What part of date planning do you enjoy most?", + "type": "multi_choice", + "text": "Choose what makes dinner together feel less routine:", "depth": 1, - "access": "premium", + "access": "free", "tags": [ - "planning", - "enjoyment" + "date_night", + "multi_choice", + "dinner" + ], + "options": [ + { + "id": "a", + "text": "A place neither of us has to defend" + }, + { + "id": "b", + "text": "A corner table" + }, + { + "id": "c", + "text": "No phones on the table" + }, + { + "id": "d", + "text": "A dessert we split" + }, + { + "id": "e", + "text": "A shared appetizer" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A place neither of us has to defend" + }, + { + "id": "b", + "text": "A corner table" + }, + { + "id": "c", + "text": "No phones on the table" + }, + { + "id": "d", + "text": "A dessert we split" + }, + { + "id": "e", + "text": "A shared appetizer" + } + ] } }, { "id": "date_night_065", "category_id": "date_night", - "type": "written", - "text": "What part of date planning feels like a burden?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "Select every dinner-date idea we would actually enjoy:", + "depth": 1, + "access": "free", "tags": [ - "planning", - "stress" + "date_night", + "multi_choice", + "dinner" + ], + "options": [ + { + "id": "a", + "text": "A shared appetizer for this date" + }, + { + "id": "b", + "text": "A corner table" + }, + { + "id": "c", + "text": "A dessert we split for this date" + }, + { + "id": "d", + "text": "Ordering something new for this date" + }, + { + "id": "e", + "text": "A toast before eating for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A shared appetizer for this date" + }, + { + "id": "b", + "text": "A corner table" + }, + { + "id": "c", + "text": "A dessert we split for this date" + }, + { + "id": "d", + "text": "Ordering something new for this date" + }, + { + "id": "e", + "text": "A toast before eating for this date" + } + ] } }, { "id": "date_night_066", "category_id": "date_night", - "type": "written", - "text": "What is one way we could share the planning better?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "Pick the simple date ideas that still count:", + "depth": 1, + "access": "free", "tags": [ - "planning", - "teamwork" + "date_night", + "multi_choice", + "coffee_walk" + ], + "options": [ + { + "id": "a", + "text": "Coffee and a walk" + }, + { + "id": "b", + "text": "A bakery stop" + }, + { + "id": "c", + "text": "A park bench conversation" + }, + { + "id": "d", + "text": "A bookstore browse" + }, + { + "id": "e", + "text": "A farmers market lap" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Coffee and a walk" + }, + { + "id": "b", + "text": "A bakery stop" + }, + { + "id": "c", + "text": "A park bench conversation" + }, + { + "id": "d", + "text": "A bookstore browse" + }, + { + "id": "e", + "text": "A farmers market lap" + } + ] } }, { "id": "date_night_067", "category_id": "date_night", - "type": "written", - "text": "What helps a planned date feel exciting instead of scheduled?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "Which low-pressure plans sound good this week?", + "depth": 1, + "access": "free", "tags": [ - "planning", - "excitement" + "date_night", + "multi_choice", + "coffee_walk" + ], + "options": [ + { + "id": "a", + "text": "A bookstore browse" + }, + { + "id": "b", + "text": "A scenic drive" + }, + { + "id": "c", + "text": "A park bench conversation" + }, + { + "id": "d", + "text": "Ice cream after dinner" + }, + { + "id": "e", + "text": "A farmers market lap" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A bookstore browse" + }, + { + "id": "b", + "text": "A scenic drive" + }, + { + "id": "c", + "text": "A park bench conversation" + }, + { + "id": "d", + "text": "Ice cream after dinner" + }, + { + "id": "e", + "text": "A farmers market lap" + } + ] } }, { "id": "date_night_068", "category_id": "date_night", - "type": "written", - "text": "What makes a spontaneous date feel fun instead of chaotic?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "What could make a short date feel worth it?", + "depth": 1, + "access": "free", "tags": [ - "spontaneity", - "comfort" + "date_night", + "multi_choice", + "coffee_walk" + ], + "options": [ + { + "id": "a", + "text": "A farmers market lap" + }, + { + "id": "b", + "text": "A scenic drive" + }, + { + "id": "c", + "text": "Ice cream after dinner" + }, + { + "id": "d", + "text": "A morning breakfast date" + }, + { + "id": "e", + "text": "Coffee and a walk for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A farmers market lap" + }, + { + "id": "b", + "text": "A scenic drive" + }, + { + "id": "c", + "text": "Ice cream after dinner" + }, + { + "id": "d", + "text": "A morning breakfast date" + }, + { + "id": "e", + "text": "Coffee and a walk for this date" + } + ] } }, { "id": "date_night_069", "category_id": "date_night", - "type": "written", - "text": "What should I know before surprising you with a date?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "Choose the easy date ideas we would not bail on:", + "depth": 1, + "access": "free", "tags": [ - "surprise", - "preference" + "date_night", + "multi_choice", + "coffee_walk" + ], + "options": [ + { + "id": "a", + "text": "A morning breakfast date" + }, + { + "id": "b", + "text": "A bakery stop" + }, + { + "id": "c", + "text": "Ice cream after dinner" + }, + { + "id": "d", + "text": "A park bench conversation" + }, + { + "id": "e", + "text": "Coffee and a walk with a twist" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A morning breakfast date" + }, + { + "id": "b", + "text": "A bakery stop" + }, + { + "id": "c", + "text": "Ice cream after dinner" + }, + { + "id": "d", + "text": "A park bench conversation" + }, + { + "id": "e", + "text": "Coffee and a walk with a twist" + } + ] } }, { "id": "date_night_070", "category_id": "date_night", - "type": "written", - "text": "What kind of surprise feels thoughtful to you?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "Select the quick plans that still feel like us:", + "depth": 1, + "access": "free", "tags": [ - "surprise", - "thoughtful" + "date_night", + "multi_choice", + "coffee_walk" + ], + "options": [ + { + "id": "a", + "text": "Coffee and a walk somewhere new" + }, + { + "id": "b", + "text": "A bakery stop" + }, + { + "id": "c", + "text": "A park bench conversation for this date" + }, + { + "id": "d", + "text": "A bookstore browse" + }, + { + "id": "e", + "text": "A farmers market lap for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Coffee and a walk somewhere new" + }, + { + "id": "b", + "text": "A bakery stop" + }, + { + "id": "c", + "text": "A park bench conversation for this date" + }, + { + "id": "d", + "text": "A bookstore browse" + }, + { + "id": "e", + "text": "A farmers market lap for this date" + } + ] } }, { "id": "date_night_071", "category_id": "date_night", - "type": "written", - "text": "What would make you feel chosen on a date with me?", - "depth": 3, - "access": "premium", + "type": "multi_choice", + "text": "Pick the music touches that would make the date better:", + "depth": 1, + "access": "free", "tags": [ - "feeling_wanted", - "romance" + "date_night", + "multi_choice", + "music" + ], + "options": [ + { + "id": "a", + "text": "A playlist for the drive" + }, + { + "id": "b", + "text": "One song each before we leave" + }, + { + "id": "c", + "text": "A slow song at home" + }, + { + "id": "d", + "text": "Live music somewhere small" + }, + { + "id": "e", + "text": "A shared old favorite" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A playlist for the drive" + }, + { + "id": "b", + "text": "One song each before we leave" + }, + { + "id": "c", + "text": "A slow song at home" + }, + { + "id": "d", + "text": "Live music somewhere small" + }, + { + "id": "e", + "text": "A shared old favorite" + } + ] } }, { "id": "date_night_072", "category_id": "date_night", - "type": "written", - "text": "What makes you feel like I really wanted time with you?", - "depth": 3, - "access": "premium", + "type": "multi_choice", + "text": "Which playlist ideas would fit date night?", + "depth": 1, + "access": "free", "tags": [ - "feeling_wanted", - "attention" + "date_night", + "multi_choice", + "music" + ], + "options": [ + { + "id": "a", + "text": "Live music somewhere small" + }, + { + "id": "b", + "text": "A song that feels like us" + }, + { + "id": "c", + "text": "A slow song at home" + }, + { + "id": "d", + "text": "Music while we cook" + }, + { + "id": "e", + "text": "A shared old favorite" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Live music somewhere small" + }, + { + "id": "b", + "text": "A song that feels like us" + }, + { + "id": "c", + "text": "A slow song at home" + }, + { + "id": "d", + "text": "Music while we cook" + }, + { + "id": "e", + "text": "A shared old favorite" + } + ] } }, { "id": "date_night_073", "category_id": "date_night", - "type": "written", - "text": "What is one thing I do on dates that makes you feel cared for?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "What should the soundtrack for our next date include?", + "depth": 1, + "access": "free", "tags": [ - "care", - "appreciation" + "date_night", + "multi_choice", + "music" + ], + "options": [ + { + "id": "a", + "text": "A shared old favorite" + }, + { + "id": "b", + "text": "A song that feels like us" + }, + { + "id": "c", + "text": "Music while we cook" + }, + { + "id": "d", + "text": "A no-skip dinner playlist" + }, + { + "id": "e", + "text": "A playlist for the drive" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A shared old favorite" + }, + { + "id": "b", + "text": "A song that feels like us" + }, + { + "id": "c", + "text": "Music while we cook" + }, + { + "id": "d", + "text": "A no-skip dinner playlist" + }, + { + "id": "e", + "text": "A playlist for the drive" + } + ] } }, { "id": "date_night_074", "category_id": "date_night", - "type": "written", - "text": "What is one thing I could do more often on dates?", - "depth": 2, - "access": "premium", + "type": "multi_choice", + "text": "Choose the music moves that sound like us:", + "depth": 1, + "access": "free", "tags": [ - "care", - "growth" + "date_night", + "multi_choice", + "music" + ], + "options": [ + { + "id": "a", + "text": "A no-skip dinner playlist" + }, + { + "id": "b", + "text": "One song each before we leave" + }, + { + "id": "c", + "text": "Music while we cook" + }, + { + "id": "d", + "text": "A slow song at home for this date" + }, + { + "id": "e", + "text": "A playlist for the drive for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A no-skip dinner playlist" + }, + { + "id": "b", + "text": "One song each before we leave" + }, + { + "id": "c", + "text": "Music while we cook" + }, + { + "id": "d", + "text": "A slow song at home for this date" + }, + { + "id": "e", + "text": "A playlist for the drive for this date" + } + ] } }, { "id": "date_night_075", "category_id": "date_night", - "type": "written", - "text": "What kind of attention from me feels most romantic?", - "depth": 3, - "access": "premium", + "type": "multi_choice", + "text": "Select anything that would make the date sound better:", + "depth": 1, + "access": "free", "tags": [ - "romance", - "attention" + "date_night", + "multi_choice", + "music" + ], + "options": [ + { + "id": "a", + "text": "A playlist for the drive with a twist" + }, + { + "id": "b", + "text": "One song each before we leave" + }, + { + "id": "c", + "text": "A slow song at home with a twist" + }, + { + "id": "d", + "text": "Live music somewhere small" + }, + { + "id": "e", + "text": "A shared old favorite for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A playlist for the drive with a twist" + }, + { + "id": "b", + "text": "One song each before we leave" + }, + { + "id": "c", + "text": "A slow song at home with a twist" + }, + { + "id": "d", + "text": "Live music somewhere small" + }, + { + "id": "e", + "text": "A shared old favorite for this date" + } + ] } }, { "id": "date_night_076", "category_id": "date_night", - "type": "written", - "text": "What kind of affection feels sweet during a date?", - "depth": 2, + "type": "multi_choice", + "text": "Pick the surprises that would actually land well:", + "depth": 1, "access": "premium", "tags": [ - "affection", - "romance" + "date_night", + "multi_choice", + "surprise" + ], + "options": [ + { + "id": "a", + "text": "A dessert already picked" + }, + { + "id": "b", + "text": "A place chosen from our saved list" + }, + { + "id": "c", + "text": "A handwritten note" + }, + { + "id": "d", + "text": "A small flower stop" + }, + { + "id": "e", + "text": "A mystery drink order" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A dessert already picked" + }, + { + "id": "b", + "text": "A place chosen from our saved list" + }, + { + "id": "c", + "text": "A handwritten note" + }, + { + "id": "d", + "text": "A small flower stop" + }, + { + "id": "e", + "text": "A mystery drink order" + } + ] } }, { "id": "date_night_077", "category_id": "date_night", - "type": "written", - "text": "What helps physical affection feel natural on a date?", - "depth": 3, + "type": "multi_choice", + "text": "Which small surprises sound sweet, not stressful?", + "depth": 1, "access": "premium", "tags": [ - "affection", - "comfort" + "date_night", + "multi_choice", + "surprise" + ], + "options": [ + { + "id": "a", + "text": "A small flower stop" + }, + { + "id": "b", + "text": "A scenic route home" + }, + { + "id": "c", + "text": "A handwritten note" + }, + { + "id": "d", + "text": "A table booked ahead" + }, + { + "id": "e", + "text": "A mystery drink order" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A small flower stop" + }, + { + "id": "b", + "text": "A scenic route home" + }, + { + "id": "c", + "text": "A handwritten note" + }, + { + "id": "d", + "text": "A table booked ahead" + }, + { + "id": "e", + "text": "A mystery drink order" + } + ] } }, { "id": "date_night_078", "category_id": "date_night", - "type": "written", - "text": "What makes you feel relaxed enough to be affectionate?", - "depth": 3, + "type": "multi_choice", + "text": "What could one of us surprise the other with?", + "depth": 1, "access": "premium", "tags": [ - "affection", - "relaxation" + "date_night", + "multi_choice", + "surprise" + ], + "options": [ + { + "id": "a", + "text": "A mystery drink order" + }, + { + "id": "b", + "text": "A scenic route home" + }, + { + "id": "c", + "text": "A table booked ahead" + }, + { + "id": "d", + "text": "A favorite snack waiting" + }, + { + "id": "e", + "text": "A dessert already picked" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A mystery drink order" + }, + { + "id": "b", + "text": "A scenic route home" + }, + { + "id": "c", + "text": "A table booked ahead" + }, + { + "id": "d", + "text": "A favorite snack waiting" + }, + { + "id": "e", + "text": "A dessert already picked" + } + ] } }, { "id": "date_night_079", "category_id": "date_night", - "type": "written", - "text": "What is a romantic detail you notice more than I realize?", - "depth": 2, + "type": "multi_choice", + "text": "Choose the date-night surprises that feel safe:", + "depth": 1, "access": "premium", "tags": [ - "romance", - "details" + "date_night", + "multi_choice", + "surprise" + ], + "options": [ + { + "id": "a", + "text": "A favorite snack waiting" + }, + { + "id": "b", + "text": "A place chosen from our saved list" + }, + { + "id": "c", + "text": "A table booked ahead" + }, + { + "id": "d", + "text": "A handwritten note" + }, + { + "id": "e", + "text": "A dessert already picked" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A favorite snack waiting" + }, + { + "id": "b", + "text": "A place chosen from our saved list" + }, + { + "id": "c", + "text": "A table booked ahead" + }, + { + "id": "d", + "text": "A handwritten note" + }, + { + "id": "e", + "text": "A dessert already picked" + } + ] } }, { "id": "date_night_080", "category_id": "date_night", - "type": "written", - "text": "What kind of compliment feels good to hear on a date?", - "depth": 2, + "type": "multi_choice", + "text": "Select the surprise touches we would both enjoy:", + "depth": 1, "access": "premium", "tags": [ - "compliments", - "romance" + "date_night", + "multi_choice", + "surprise" + ], + "options": [ + { + "id": "a", + "text": "A dessert already picked for this date" + }, + { + "id": "b", + "text": "A place chosen from our saved list" + }, + { + "id": "c", + "text": "A handwritten note for this date" + }, + { + "id": "d", + "text": "A small flower stop" + }, + { + "id": "e", + "text": "A mystery drink order for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A dessert already picked for this date" + }, + { + "id": "b", + "text": "A place chosen from our saved list" + }, + { + "id": "c", + "text": "A handwritten note for this date" + }, + { + "id": "d", + "text": "A small flower stop" + }, + { + "id": "e", + "text": "A mystery drink order for this date" + } + ] } }, { "id": "date_night_081", "category_id": "date_night", - "type": "written", - "text": "What makes a date feel flirty in a way you enjoy?", - "depth": 2, + "type": "multi_choice", + "text": "Pick the flirty date moves that would work on us:", + "depth": 1, "access": "premium", "tags": [ - "flirting", - "playfulness" + "date_night", + "multi_choice", + "flirty" + ], + "options": [ + { + "id": "a", + "text": "A compliment before we leave" + }, + { + "id": "b", + "text": "Holding hands more" + }, + { + "id": "c", + "text": "A kiss before dinner" + }, + { + "id": "d", + "text": "A message before the date" + }, + { + "id": "e", + "text": "A slower goodbye" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A compliment before we leave" + }, + { + "id": "b", + "text": "Holding hands more" + }, + { + "id": "c", + "text": "A kiss before dinner" + }, + { + "id": "d", + "text": "A message before the date" + }, + { + "id": "e", + "text": "A slower goodbye" + } + ] } }, { "id": "date_night_082", "category_id": "date_night", - "type": "written", - "text": "What helps you feel pursued, not just scheduled?", - "depth": 3, + "type": "multi_choice", + "text": "Which little sparks should date night include?", + "depth": 1, "access": "premium", "tags": [ - "feeling_wanted", - "romance" + "date_night", + "multi_choice", + "flirty" + ], + "options": [ + { + "id": "a", + "text": "A message before the date" + }, + { + "id": "b", + "text": "Sitting closer than usual" + }, + { + "id": "c", + "text": "A kiss before dinner" + }, + { + "id": "d", + "text": "A dressed-up moment" + }, + { + "id": "e", + "text": "A slower goodbye" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A message before the date" + }, + { + "id": "b", + "text": "Sitting closer than usual" + }, + { + "id": "c", + "text": "A kiss before dinner" + }, + { + "id": "d", + "text": "A dressed-up moment" + }, + { + "id": "e", + "text": "A slower goodbye" + } + ] } }, { "id": "date_night_083", "category_id": "date_night", - "type": "written", - "text": "What is one way I could make our next date feel more personal?", - "depth": 2, + "type": "multi_choice", + "text": "What would make the date feel more romantic?", + "depth": 1, "access": "premium", "tags": [ - "personal", - "thoughtful" + "date_night", + "multi_choice", + "flirty" + ], + "options": [ + { + "id": "a", + "text": "A slower goodbye" + }, + { + "id": "b", + "text": "Sitting closer than usual" + }, + { + "id": "c", + "text": "A dressed-up moment" + }, + { + "id": "d", + "text": "A song that makes us smile" + }, + { + "id": "e", + "text": "A compliment before we leave" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A slower goodbye" + }, + { + "id": "b", + "text": "Sitting closer than usual" + }, + { + "id": "c", + "text": "A dressed-up moment" + }, + { + "id": "d", + "text": "A song that makes us smile" + }, + { + "id": "e", + "text": "A compliment before we leave" + } + ] } }, { "id": "date_night_084", "category_id": "date_night", - "type": "written", - "text": "What makes a date feel special even if it is simple?", - "depth": 2, + "type": "multi_choice", + "text": "Choose the flirty details that sound natural:", + "depth": 1, "access": "premium", "tags": [ - "simple_dates", - "special" + "date_night", + "multi_choice", + "flirty" + ], + "options": [ + { + "id": "a", + "text": "A song that makes us smile" + }, + { + "id": "b", + "text": "Holding hands more" + }, + { + "id": "c", + "text": "A dressed-up moment" + }, + { + "id": "d", + "text": "A kiss before dinner" + }, + { + "id": "e", + "text": "A compliment before we leave" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A song that makes us smile" + }, + { + "id": "b", + "text": "Holding hands more" + }, + { + "id": "c", + "text": "A dressed-up moment" + }, + { + "id": "d", + "text": "A kiss before dinner" + }, + { + "id": "e", + "text": "A compliment before we leave" + } + ] } }, { "id": "date_night_085", "category_id": "date_night", - "type": "written", - "text": "What is a date memory where you felt really wanted by me?", - "depth": 3, + "type": "multi_choice", + "text": "Select anything that would bring date-night chemistry:", + "depth": 1, "access": "premium", "tags": [ - "memories", - "feeling_wanted" + "date_night", + "multi_choice", + "flirty" + ], + "options": [ + { + "id": "a", + "text": "A compliment before we leave for this date" + }, + { + "id": "b", + "text": "Holding hands more for this date" + }, + { + "id": "c", + "text": "A kiss before dinner for this date" + }, + { + "id": "d", + "text": "A message before the date" + }, + { + "id": "e", + "text": "A slower goodbye for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A compliment before we leave for this date" + }, + { + "id": "b", + "text": "Holding hands more for this date" + }, + { + "id": "c", + "text": "A kiss before dinner for this date" + }, + { + "id": "d", + "text": "A message before the date" + }, + { + "id": "e", + "text": "A slower goodbye for this date" + } + ] } }, { "id": "date_night_086", "category_id": "date_night", - "type": "written", - "text": "What is a date memory where you felt really close to me?", - "depth": 3, + "type": "multi_choice", + "text": "Pick the new-place ideas worth trying:", + "depth": 1, "access": "premium", "tags": [ - "memories", - "closeness" + "date_night", + "multi_choice", + "new_place" + ], + "options": [ + { + "id": "a", + "text": "A restaurant we keep mentioning" + }, + { + "id": "b", + "text": "A coffee shop across town" + }, + { + "id": "c", + "text": "A small live show" + }, + { + "id": "d", + "text": "A museum or exhibit" + }, + { + "id": "e", + "text": "A food truck we notice" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A restaurant we keep mentioning" + }, + { + "id": "b", + "text": "A coffee shop across town" + }, + { + "id": "c", + "text": "A small live show" + }, + { + "id": "d", + "text": "A museum or exhibit" + }, + { + "id": "e", + "text": "A food truck we notice" + } + ] } }, { "id": "date_night_087", "category_id": "date_night", - "type": "written", - "text": "What do you wish we brought back from when we first started dating?", - "depth": 3, + "type": "multi_choice", + "text": "Which new spots should make the date list?", + "depth": 1, "access": "premium", "tags": [ - "early_days", - "renewal" + "date_night", + "multi_choice", + "new_place" + ], + "options": [ + { + "id": "a", + "text": "A museum or exhibit" + }, + { + "id": "b", + "text": "A pretty patio" + }, + { + "id": "c", + "text": "A small live show" + }, + { + "id": "d", + "text": "A new breakfast place" + }, + { + "id": "e", + "text": "A food truck we notice" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A museum or exhibit" + }, + { + "id": "b", + "text": "A pretty patio" + }, + { + "id": "c", + "text": "A small live show" + }, + { + "id": "d", + "text": "A new breakfast place" + }, + { + "id": "e", + "text": "A food truck we notice" + } + ] } }, { "id": "date_night_088", "category_id": "date_night", - "type": "written", - "text": "What did I do early on that still makes you smile?", - "depth": 2, + "type": "multi_choice", + "text": "What should we explore on a future date?", + "depth": 1, "access": "premium", "tags": [ - "early_days", - "memories" + "date_night", + "multi_choice", + "new_place" + ], + "options": [ + { + "id": "a", + "text": "A food truck we notice" + }, + { + "id": "b", + "text": "A pretty patio" + }, + { + "id": "c", + "text": "A new breakfast place" + }, + { + "id": "d", + "text": "A neighborhood walk" + }, + { + "id": "e", + "text": "A restaurant we keep mentioning" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A food truck we notice" + }, + { + "id": "b", + "text": "A pretty patio" + }, + { + "id": "c", + "text": "A new breakfast place" + }, + { + "id": "d", + "text": "A neighborhood walk" + }, + { + "id": "e", + "text": "A restaurant we keep mentioning" + } + ] } }, { "id": "date_night_089", "category_id": "date_night", - "type": "written", - "text": "What is one little ritual we could start for date nights?", - "depth": 2, + "type": "multi_choice", + "text": "Choose the places that sound like our speed:", + "depth": 1, "access": "premium", "tags": [ - "rituals", - "tradition" + "date_night", + "multi_choice", + "new_place" + ], + "options": [ + { + "id": "a", + "text": "A neighborhood walk" + }, + { + "id": "b", + "text": "A coffee shop across town" + }, + { + "id": "c", + "text": "A new breakfast place" + }, + { + "id": "d", + "text": "A small live show" + }, + { + "id": "e", + "text": "A restaurant we keep mentioning" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A neighborhood walk" + }, + { + "id": "b", + "text": "A coffee shop across town" + }, + { + "id": "c", + "text": "A new breakfast place" + }, + { + "id": "d", + "text": "A small live show" + }, + { + "id": "e", + "text": "A restaurant we keep mentioning" + } + ] } }, { "id": "date_night_090", "category_id": "date_night", - "type": "written", - "text": "What would make saying yes to dates easier right now?", - "depth": 2, + "type": "multi_choice", + "text": "Select the local date ideas we should not forget:", + "depth": 1, "access": "premium", "tags": [ - "ease", - "busy_life" + "date_night", + "multi_choice", + "new_place" + ], + "options": [ + { + "id": "a", + "text": "A restaurant we keep mentioning for this date" + }, + { + "id": "b", + "text": "A coffee shop across town" + }, + { + "id": "c", + "text": "A small live show for this date" + }, + { + "id": "d", + "text": "A museum or exhibit for this date" + }, + { + "id": "e", + "text": "A food truck we notice for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A restaurant we keep mentioning for this date" + }, + { + "id": "b", + "text": "A coffee shop across town" + }, + { + "id": "c", + "text": "A small live show for this date" + }, + { + "id": "d", + "text": "A museum or exhibit for this date" + }, + { + "id": "e", + "text": "A food truck we notice for this date" + } + ] } }, { "id": "date_night_091", "category_id": "date_night", - "type": "written", - "text": "What tends to make date night harder for you to enjoy?", - "depth": 2, + "type": "multi_choice", + "text": "Pick the budget-friendly dates that still feel good:", + "depth": 1, "access": "premium", "tags": [ - "stress", - "awareness" + "date_night", + "multi_choice", + "budget" + ], + "options": [ + { + "id": "a", + "text": "A picnic with favorites" + }, + { + "id": "b", + "text": "Homemade dessert" + }, + { + "id": "c", + "text": "A free local event" + }, + { + "id": "d", + "text": "Coffee and a walk before dessert" + }, + { + "id": "e", + "text": "A movie night with intention" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A picnic with favorites" + }, + { + "id": "b", + "text": "Homemade dessert" + }, + { + "id": "c", + "text": "A free local event" + }, + { + "id": "d", + "text": "Coffee and a walk before dessert" + }, + { + "id": "e", + "text": "A movie night with intention" + } + ] } }, { "id": "date_night_092", "category_id": "date_night", - "type": "written", - "text": "What should we do when one of us is too tired for the plan?", - "depth": 2, + "type": "multi_choice", + "text": "Which low-cost date ideas are worth keeping?", + "depth": 1, "access": "premium", "tags": [ - "tired", - "flexibility" + "date_night", + "multi_choice", + "budget" + ], + "options": [ + { + "id": "a", + "text": "Coffee and a walk after dinner" + }, + { + "id": "b", + "text": "A shared grocery-store treat" + }, + { + "id": "c", + "text": "A free local event" + }, + { + "id": "d", + "text": "A sunset drive" + }, + { + "id": "e", + "text": "A movie night with intention" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Coffee and a walk after dinner" + }, + { + "id": "b", + "text": "A shared grocery-store treat" + }, + { + "id": "c", + "text": "A free local event" + }, + { + "id": "d", + "text": "A sunset drive" + }, + { + "id": "e", + "text": "A movie night with intention" + } + ] } }, { "id": "date_night_093", "category_id": "date_night", - "type": "written", - "text": "What is a backup date we could use when plans fall apart?", + "type": "multi_choice", + "text": "What can feel special without spending much?", "depth": 1, "access": "premium", "tags": [ - "backup_plan", - "ease" + "date_night", + "multi_choice", + "budget" + ], + "options": [ + { + "id": "a", + "text": "A movie night with intention" + }, + { + "id": "b", + "text": "A shared grocery-store treat" + }, + { + "id": "c", + "text": "A sunset drive" + }, + { + "id": "d", + "text": "A card game with drinks" + }, + { + "id": "e", + "text": "A picnic with favorites" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A movie night with intention" + }, + { + "id": "b", + "text": "A shared grocery-store treat" + }, + { + "id": "c", + "text": "A sunset drive" + }, + { + "id": "d", + "text": "A card game with drinks" + }, + { + "id": "e", + "text": "A picnic with favorites" + } + ] } }, { "id": "date_night_094", "category_id": "date_night", - "type": "written", - "text": "What helps a cancelled plan still feel like we chose each other?", - "depth": 3, + "type": "multi_choice", + "text": "Choose the cheap dates that do not feel cheap:", + "depth": 1, "access": "premium", "tags": [ - "disappointment", - "repair" + "date_night", + "multi_choice", + "budget" + ], + "options": [ + { + "id": "a", + "text": "A card game with drinks" + }, + { + "id": "b", + "text": "Homemade dessert" + }, + { + "id": "c", + "text": "A sunset drive" + }, + { + "id": "d", + "text": "A free local event for this date" + }, + { + "id": "e", + "text": "A picnic with favorites for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A card game with drinks" + }, + { + "id": "b", + "text": "Homemade dessert" + }, + { + "id": "c", + "text": "A sunset drive" + }, + { + "id": "d", + "text": "A free local event for this date" + }, + { + "id": "e", + "text": "A picnic with favorites for this date" + } + ] } }, { "id": "date_night_095", "category_id": "date_night", - "type": "written", - "text": "What would help us protect date time from everyday stress?", - "depth": 2, + "type": "multi_choice", + "text": "Select the simple plans that fit a budget:", + "depth": 1, "access": "premium", "tags": [ - "stress", - "protect_time" + "date_night", + "multi_choice", + "budget" + ], + "options": [ + { + "id": "a", + "text": "A picnic with favorites with a twist" + }, + { + "id": "b", + "text": "Homemade dessert" + }, + { + "id": "c", + "text": "A free local event with a twist" + }, + { + "id": "d", + "text": "Coffee and a walk this month" + }, + { + "id": "e", + "text": "A movie night with intention for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A picnic with favorites with a twist" + }, + { + "id": "b", + "text": "Homemade dessert" + }, + { + "id": "c", + "text": "A free local event with a twist" + }, + { + "id": "d", + "text": "Coffee and a walk this month" + }, + { + "id": "e", + "text": "A movie night with intention for this date" + } + ] } }, { "id": "date_night_096", "category_id": "date_night", - "type": "written", - "text": "What makes date night feel like another task, and how can we avoid that?", - "depth": 2, + "type": "multi_choice", + "text": "Pick the little celebration moves that sound good:", + "depth": 1, "access": "premium", "tags": [ - "task_load", - "ease" + "date_night", + "multi_choice", + "celebration" + ], + "options": [ + { + "id": "a", + "text": "A nicer dessert" + }, + { + "id": "b", + "text": "A photo together" + }, + { + "id": "c", + "text": "A toast at dinner" + }, + { + "id": "d", + "text": "A favorite restaurant" + }, + { + "id": "e", + "text": "A slow morning brunch" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A nicer dessert" + }, + { + "id": "b", + "text": "A photo together" + }, + { + "id": "c", + "text": "A toast at dinner" + }, + { + "id": "d", + "text": "A favorite restaurant" + }, + { + "id": "e", + "text": "A slow morning brunch" + } + ] } }, { "id": "date_night_097", "category_id": "date_night", - "type": "written", - "text": "What would make you more excited to plan something together?", - "depth": 2, + "type": "multi_choice", + "text": "Which date ideas fit a small win?", + "depth": 1, "access": "premium", "tags": [ - "planning", - "excitement" + "date_night", + "multi_choice", + "celebration" + ], + "options": [ + { + "id": "a", + "text": "A favorite restaurant" + }, + { + "id": "b", + "text": "A new outfit moment" + }, + { + "id": "c", + "text": "A toast at dinner" + }, + { + "id": "d", + "text": "A pretty view" + }, + { + "id": "e", + "text": "A slow morning brunch" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A favorite restaurant" + }, + { + "id": "b", + "text": "A new outfit moment" + }, + { + "id": "c", + "text": "A toast at dinner" + }, + { + "id": "d", + "text": "A pretty view" + }, + { + "id": "e", + "text": "A slow morning brunch" + } + ] } }, { "id": "date_night_098", "category_id": "date_night", - "type": "written", - "text": "What is one small thing we could do before a date to get in a better mood?", - "depth": 2, + "type": "multi_choice", + "text": "What should we do when we have something to celebrate?", + "depth": 1, "access": "premium", "tags": [ - "pre_date", - "mood" + "date_night", + "multi_choice", + "celebration" + ], + "options": [ + { + "id": "a", + "text": "A slow morning brunch for this date" + }, + { + "id": "b", + "text": "A new outfit moment" + }, + { + "id": "c", + "text": "A pretty view" + }, + { + "id": "d", + "text": "A shared appetizer with a twist" + }, + { + "id": "e", + "text": "A nicer dessert" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A slow morning brunch for this date" + }, + { + "id": "b", + "text": "A new outfit moment" + }, + { + "id": "c", + "text": "A pretty view" + }, + { + "id": "d", + "text": "A shared appetizer with a twist" + }, + { + "id": "e", + "text": "A nicer dessert" + } + ] } }, { "id": "date_night_099", "category_id": "date_night", - "type": "written", - "text": "What helps you switch from busy mode into couple mode?", - "depth": 2, + "type": "multi_choice", + "text": "Choose the date touches that feel celebratory:", + "depth": 1, "access": "premium", "tags": [ - "busy_life", - "transition" + "date_night", + "multi_choice", + "celebration" + ], + "options": [ + { + "id": "a", + "text": "A shared appetizer somewhere new" + }, + { + "id": "b", + "text": "A photo together" + }, + { + "id": "c", + "text": "A pretty view" + }, + { + "id": "d", + "text": "A toast at dinner" + }, + { + "id": "e", + "text": "A nicer dessert for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A shared appetizer somewhere new" + }, + { + "id": "b", + "text": "A photo together" + }, + { + "id": "c", + "text": "A pretty view" + }, + { + "id": "d", + "text": "A toast at dinner" + }, + { + "id": "e", + "text": "A nicer dessert for this date" + } + ] } }, { "id": "date_night_100", "category_id": "date_night", - "type": "written", - "text": "What would help us stop talking only about logistics on dates?", - "depth": 2, + "type": "multi_choice", + "text": "Select the small wins worth turning into a date:", + "depth": 1, "access": "premium", "tags": [ - "conversation", - "logistics" + "date_night", + "multi_choice", + "celebration" + ], + "options": [ + { + "id": "a", + "text": "A nicer dessert with a twist" + }, + { + "id": "b", + "text": "A photo together" + }, + { + "id": "c", + "text": "A toast at dinner for this date" + }, + { + "id": "d", + "text": "A favorite restaurant for this date" + }, + { + "id": "e", + "text": "A slow morning brunch with a twist" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A nicer dessert with a twist" + }, + { + "id": "b", + "text": "A photo together" + }, + { + "id": "c", + "text": "A toast at dinner for this date" + }, + { + "id": "d", + "text": "A favorite restaurant for this date" + }, + { + "id": "e", + "text": "A slow morning brunch with a twist" + } + ] } }, { "id": "date_night_101", "category_id": "date_night", - "type": "written", - "text": "What makes you feel like we are dating each other, not just managing life?", - "depth": 3, + "type": "multi_choice", + "text": "Pick the after-work dates that would not feel exhausting:", + "depth": 1, "access": "premium", "tags": [ - "renewal", - "busy_life" + "date_night", + "multi_choice", + "after_work" + ], + "options": [ + { + "id": "a", + "text": "Dinner close by" + }, + { + "id": "b", + "text": "Takeout with a real setup" + }, + { + "id": "c", + "text": "A short dessert run" + }, + { + "id": "d", + "text": "A walk before home" + }, + { + "id": "e", + "text": "A movie already chosen" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Dinner close by" + }, + { + "id": "b", + "text": "Takeout with a real setup" + }, + { + "id": "c", + "text": "A short dessert run" + }, + { + "id": "d", + "text": "A walk before home" + }, + { + "id": "e", + "text": "A movie already chosen" + } + ] } }, { "id": "date_night_102", "category_id": "date_night", - "type": "written", - "text": "What kind of date helps us reconnect after a stressful week?", - "depth": 3, + "type": "multi_choice", + "text": "Which weeknight date ideas sound realistic?", + "depth": 1, "access": "premium", "tags": [ - "reconnect", - "stress" + "date_night", + "multi_choice", + "after_work" + ], + "options": [ + { + "id": "a", + "text": "A walk before home" + }, + { + "id": "b", + "text": "A simple drink together" + }, + { + "id": "c", + "text": "A short dessert run" + }, + { + "id": "d", + "text": "Coffee after work" + }, + { + "id": "e", + "text": "A movie already chosen" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A walk before home" + }, + { + "id": "b", + "text": "A simple drink together" + }, + { + "id": "c", + "text": "A short dessert run" + }, + { + "id": "d", + "text": "Coffee after work" + }, + { + "id": "e", + "text": "A movie already chosen" + } + ] } }, { "id": "date_night_103", "category_id": "date_night", - "type": "written", - "text": "What kind of date helps us reconnect after we have felt distant?", - "depth": 3, + "type": "multi_choice", + "text": "What works when the date has to be easy?", + "depth": 1, "access": "premium", "tags": [ - "reconnect", - "distance" + "date_night", + "multi_choice", + "after_work" + ], + "options": [ + { + "id": "a", + "text": "A movie already chosen" + }, + { + "id": "b", + "text": "A simple drink together" + }, + { + "id": "c", + "text": "Coffee after work" + }, + { + "id": "d", + "text": "A quick scenic drive" + }, + { + "id": "e", + "text": "Dinner close by" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A movie already chosen" + }, + { + "id": "b", + "text": "A simple drink together" + }, + { + "id": "c", + "text": "Coffee after work" + }, + { + "id": "d", + "text": "A quick scenic drive" + }, + { + "id": "e", + "text": "Dinner close by" + } + ] } }, { "id": "date_night_104", "category_id": "date_night", - "type": "written", - "text": "What is a gentle date idea for when we are not fully okay yet?", - "depth": 3, + "type": "multi_choice", + "text": "Choose the low-energy date plans we would still enjoy:", + "depth": 1, "access": "premium", "tags": [ - "repair", - "gentle" + "date_night", + "multi_choice", + "after_work" + ], + "options": [ + { + "id": "a", + "text": "A quick scenic drive" + }, + { + "id": "b", + "text": "Takeout with a real setup" + }, + { + "id": "c", + "text": "Coffee after work" + }, + { + "id": "d", + "text": "A short dessert run" + }, + { + "id": "e", + "text": "Dinner close by" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A quick scenic drive" + }, + { + "id": "b", + "text": "Takeout with a real setup" + }, + { + "id": "c", + "text": "Coffee after work" + }, + { + "id": "d", + "text": "A short dessert run" + }, + { + "id": "e", + "text": "Dinner close by" + } + ] } }, { "id": "date_night_105", "category_id": "date_night", - "type": "written", - "text": "What helps a date feel safe after we have had tension?", - "depth": 3, + "type": "multi_choice", + "text": "Select the after-work plans that feel doable:", + "depth": 1, "access": "premium", "tags": [ - "repair", - "safety" + "date_night", + "multi_choice", + "after_work" + ], + "options": [ + { + "id": "a", + "text": "Dinner close by for this date" + }, + { + "id": "b", + "text": "Takeout with a real setup" + }, + { + "id": "c", + "text": "A short dessert run for this date" + }, + { + "id": "d", + "text": "A walk before home for this date" + }, + { + "id": "e", + "text": "A movie already chosen for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Dinner close by for this date" + }, + { + "id": "b", + "text": "Takeout with a real setup" + }, + { + "id": "c", + "text": "A short dessert run for this date" + }, + { + "id": "d", + "text": "A walk before home for this date" + }, + { + "id": "e", + "text": "A movie already chosen for this date" + } + ] } }, { "id": "date_night_106", "category_id": "date_night", - "type": "written", - "text": "What should we not try to fix during date night?", - "depth": 3, + "type": "multi_choice", + "text": "Pick the rainy-day date ideas that sound good:", + "depth": 1, "access": "premium", "tags": [ - "boundaries", - "conflict" + "date_night", + "multi_choice", + "rainy_day" + ], + "options": [ + { + "id": "a", + "text": "A cafe window seat" + }, + { + "id": "b", + "text": "A movie at home" + }, + { + "id": "c", + "text": "Soup or ramen out" + }, + { + "id": "d", + "text": "A bookstore browse for this date" + }, + { + "id": "e", + "text": "A museum visit" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A cafe window seat" + }, + { + "id": "b", + "text": "A movie at home" + }, + { + "id": "c", + "text": "Soup or ramen out" + }, + { + "id": "d", + "text": "A bookstore browse for this date" + }, + { + "id": "e", + "text": "A museum visit" + } + ] } }, { "id": "date_night_107", "category_id": "date_night", - "type": "written", - "text": "What helps you feel open to me during a quieter date?", - "depth": 3, + "type": "multi_choice", + "text": "Which cozy date moves work when the weather is bad?", + "depth": 1, "access": "premium", "tags": [ - "openness", - "quiet" + "date_night", + "multi_choice", + "rainy_day" + ], + "options": [ + { + "id": "a", + "text": "A bookstore browse with a twist" + }, + { + "id": "b", + "text": "A baking attempt" + }, + { + "id": "c", + "text": "Soup or ramen out" + }, + { + "id": "d", + "text": "A puzzle with drinks" + }, + { + "id": "e", + "text": "A museum visit" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A bookstore browse with a twist" + }, + { + "id": "b", + "text": "A baking attempt" + }, + { + "id": "c", + "text": "Soup or ramen out" + }, + { + "id": "d", + "text": "A puzzle with drinks" + }, + { + "id": "e", + "text": "A museum visit" + } + ] } }, { "id": "date_night_108", "category_id": "date_night", - "type": "written", - "text": "What is one way we can use date night to enjoy each other, not solve everything?", - "depth": 3, + "type": "multi_choice", + "text": "What should a rainy date include?", + "depth": 1, "access": "premium", "tags": [ - "pressure", - "enjoyment" + "date_night", + "multi_choice", + "rainy_day" + ], + "options": [ + { + "id": "a", + "text": "A museum visit" + }, + { + "id": "b", + "text": "A baking attempt" + }, + { + "id": "c", + "text": "A puzzle with drinks" + }, + { + "id": "d", + "text": "A warm dessert stop" + }, + { + "id": "e", + "text": "A cafe window seat" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A museum visit" + }, + { + "id": "b", + "text": "A baking attempt" + }, + { + "id": "c", + "text": "A puzzle with drinks" + }, + { + "id": "d", + "text": "A warm dessert stop" + }, + { + "id": "e", + "text": "A cafe window seat" + } + ] } }, { "id": "date_night_109", "category_id": "date_night", - "type": "written", - "text": "What is one sign that a date helped us reconnect?", - "depth": 3, + "type": "multi_choice", + "text": "Choose the indoor date ideas we would enjoy:", + "depth": 1, "access": "premium", "tags": [ - "reconnect", - "signals" + "date_night", + "multi_choice", + "rainy_day" + ], + "options": [ + { + "id": "a", + "text": "A warm dessert stop" + }, + { + "id": "b", + "text": "A movie at home" + }, + { + "id": "c", + "text": "A puzzle with drinks" + }, + { + "id": "d", + "text": "Soup or ramen out" + }, + { + "id": "e", + "text": "A cafe window seat" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A warm dessert stop" + }, + { + "id": "b", + "text": "A movie at home" + }, + { + "id": "c", + "text": "A puzzle with drinks" + }, + { + "id": "d", + "text": "Soup or ramen out" + }, + { + "id": "e", + "text": "A cafe window seat" + } + ] } }, { "id": "date_night_110", "category_id": "date_night", - "type": "written", - "text": "What makes you leave a date feeling lighter?", - "depth": 2, + "type": "multi_choice", + "text": "Select the rain-proof plans worth saving:", + "depth": 1, "access": "premium", "tags": [ - "after_date", - "mood" + "date_night", + "multi_choice", + "rainy_day" + ], + "options": [ + { + "id": "a", + "text": "A cafe window seat for this date" + }, + { + "id": "b", + "text": "A movie at home for this date" + }, + { + "id": "c", + "text": "Soup or ramen out for this date" + }, + { + "id": "d", + "text": "A bookstore browse somewhere new" + }, + { + "id": "e", + "text": "A museum visit for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A cafe window seat for this date" + }, + { + "id": "b", + "text": "A movie at home for this date" + }, + { + "id": "c", + "text": "Soup or ramen out for this date" + }, + { + "id": "d", + "text": "A bookstore browse somewhere new" + }, + { + "id": "e", + "text": "A museum visit for this date" + } + ] } }, { "id": "date_night_111", "category_id": "date_night", - "type": "written", - "text": "What makes you leave a date feeling closer to me?", - "depth": 3, + "type": "multi_choice", + "text": "Pick the weekend date ideas worth planning:", + "depth": 1, "access": "premium", "tags": [ - "after_date", - "closeness" + "date_night", + "multi_choice", + "weekend" + ], + "options": [ + { + "id": "a", + "text": "A brunch reservation" + }, + { + "id": "b", + "text": "A short day trip" + }, + { + "id": "c", + "text": "A long walk somewhere pretty" + }, + { + "id": "d", + "text": "A local event" + }, + { + "id": "e", + "text": "A new lunch spot" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A brunch reservation" + }, + { + "id": "b", + "text": "A short day trip" + }, + { + "id": "c", + "text": "A long walk somewhere pretty" + }, + { + "id": "d", + "text": "A local event" + }, + { + "id": "e", + "text": "A new lunch spot" + } + ] } }, { "id": "date_night_112", "category_id": "date_night", - "type": "written", - "text": "What do you usually hope I notice during a date?", - "depth": 3, + "type": "multi_choice", + "text": "Which weekend date pieces sound right?", + "depth": 1, "access": "premium", "tags": [ - "attention", - "care" + "date_night", + "multi_choice", + "weekend" + ], + "options": [ + { + "id": "a", + "text": "A local event" + }, + { + "id": "b", + "text": "A late movie" + }, + { + "id": "c", + "text": "A long walk somewhere pretty" + }, + { + "id": "d", + "text": "A market stop" + }, + { + "id": "e", + "text": "A new lunch spot" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A local event" + }, + { + "id": "b", + "text": "A late movie" + }, + { + "id": "c", + "text": "A long walk somewhere pretty" + }, + { + "id": "d", + "text": "A market stop" + }, + { + "id": "e", + "text": "A new lunch spot" + } + ] } }, { "id": "date_night_113", "category_id": "date_night", - "type": "written", - "text": "What is something small I could do at the end of a date that would mean a lot?", - "depth": 2, + "type": "multi_choice", + "text": "What should a better weekend date include?", + "depth": 1, "access": "premium", "tags": [ - "after_date", - "thoughtful" + "date_night", + "multi_choice", + "weekend" + ], + "options": [ + { + "id": "a", + "text": "A new lunch spot" + }, + { + "id": "b", + "text": "A late movie" + }, + { + "id": "c", + "text": "A market stop" + }, + { + "id": "d", + "text": "A drive with a playlist" + }, + { + "id": "e", + "text": "A brunch reservation" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A new lunch spot" + }, + { + "id": "b", + "text": "A late movie" + }, + { + "id": "c", + "text": "A market stop" + }, + { + "id": "d", + "text": "A drive with a playlist" + }, + { + "id": "e", + "text": "A brunch reservation" + } + ] } }, { "id": "date_night_114", "category_id": "date_night", - "type": "written", - "text": "What is one date we should take a photo during?", + "type": "multi_choice", + "text": "Choose the weekend plans that feel worth the time:", "depth": 1, "access": "premium", "tags": [ - "memories", - "photos" + "date_night", + "multi_choice", + "weekend" + ], + "options": [ + { + "id": "a", + "text": "A drive with a playlist" + }, + { + "id": "b", + "text": "A short day trip" + }, + { + "id": "c", + "text": "A market stop" + }, + { + "id": "d", + "text": "A long walk somewhere pretty" + }, + { + "id": "e", + "text": "A brunch reservation" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A drive with a playlist" + }, + { + "id": "b", + "text": "A short day trip" + }, + { + "id": "c", + "text": "A market stop" + }, + { + "id": "d", + "text": "A long walk somewhere pretty" + }, + { + "id": "e", + "text": "A brunch reservation" + } + ] } }, { "id": "date_night_115", "category_id": "date_night", - "type": "written", - "text": "What date memory would you love to recreate?", - "depth": 2, + "type": "multi_choice", + "text": "Select the date ideas that need a free afternoon:", + "depth": 1, "access": "premium", "tags": [ - "memories", - "repeat" + "date_night", + "multi_choice", + "weekend" + ], + "options": [ + { + "id": "a", + "text": "A brunch reservation for this date" + }, + { + "id": "b", + "text": "A short day trip" + }, + { + "id": "c", + "text": "A long walk somewhere pretty for this date" + }, + { + "id": "d", + "text": "A local event for this date" + }, + { + "id": "e", + "text": "A new lunch spot for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A brunch reservation for this date" + }, + { + "id": "b", + "text": "A short day trip" + }, + { + "id": "c", + "text": "A long walk somewhere pretty for this date" + }, + { + "id": "d", + "text": "A local event for this date" + }, + { + "id": "e", + "text": "A new lunch spot for this date" + } + ] } }, { "id": "date_night_116", "category_id": "date_night", - "type": "written", - "text": "What is one old favorite place we should revisit?", + "type": "multi_choice", + "text": "Pick the date ideas that feel a little more romantic:", "depth": 1, "access": "premium", "tags": [ - "memories", - "places" + "date_night", + "multi_choice", + "anniversary" + ], + "options": [ + { + "id": "a", + "text": "A place with a view" + }, + { + "id": "b", + "text": "Dressing up" + }, + { + "id": "c", + "text": "A thoughtful note" + }, + { + "id": "d", + "text": "A slow dinner" + }, + { + "id": "e", + "text": "A photo we actually like" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A place with a view" + }, + { + "id": "b", + "text": "Dressing up" + }, + { + "id": "c", + "text": "A thoughtful note" + }, + { + "id": "d", + "text": "A slow dinner" + }, + { + "id": "e", + "text": "A photo we actually like" + } + ] } }, { "id": "date_night_117", "category_id": "date_night", - "type": "written", - "text": "What is a date we talked about but never actually did?", + "type": "multi_choice", + "text": "Which special-date touches sound like us?", "depth": 1, "access": "premium", "tags": [ - "unfinished_plans", - "date_idea" + "date_night", + "multi_choice", + "anniversary" + ], + "options": [ + { + "id": "a", + "text": "A slow dinner" + }, + { + "id": "b", + "text": "A favorite memory brought up" + }, + { + "id": "c", + "text": "A thoughtful note" + }, + { + "id": "d", + "text": "A dessert worth sharing" + }, + { + "id": "e", + "text": "A photo we actually like" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A slow dinner" + }, + { + "id": "b", + "text": "A favorite memory brought up" + }, + { + "id": "c", + "text": "A thoughtful note" + }, + { + "id": "d", + "text": "A dessert worth sharing" + }, + { + "id": "e", + "text": "A photo we actually like" + } + ] } }, { "id": "date_night_118", "category_id": "date_night", - "type": "written", - "text": "What date would make a good story later?", - "depth": 2, + "type": "multi_choice", + "text": "What would make a date feel worth remembering?", + "depth": 1, "access": "premium", "tags": [ - "memories", - "adventure" + "date_night", + "multi_choice", + "anniversary" + ], + "options": [ + { + "id": "a", + "text": "A photo we actually like" + }, + { + "id": "b", + "text": "A favorite memory brought up" + }, + { + "id": "c", + "text": "A dessert worth sharing" + }, + { + "id": "d", + "text": "A plan made ahead" + }, + { + "id": "e", + "text": "A place with a view" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A photo we actually like" + }, + { + "id": "b", + "text": "A favorite memory brought up" + }, + { + "id": "c", + "text": "A dessert worth sharing" + }, + { + "id": "d", + "text": "A plan made ahead" + }, + { + "id": "e", + "text": "A place with a view" + } + ] } }, { "id": "date_night_119", "category_id": "date_night", - "type": "written", - "text": "What is one tradition you would like us to build around date night?", - "depth": 2, + "type": "multi_choice", + "text": "Choose the romantic details that do not feel forced:", + "depth": 1, "access": "premium", "tags": [ - "tradition", - "rituals" + "date_night", + "multi_choice", + "anniversary" + ], + "options": [ + { + "id": "a", + "text": "A plan made ahead" + }, + { + "id": "b", + "text": "Dressing up" + }, + { + "id": "c", + "text": "A dessert worth sharing" + }, + { + "id": "d", + "text": "A thoughtful note" + }, + { + "id": "e", + "text": "A place with a view for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A plan made ahead" + }, + { + "id": "b", + "text": "Dressing up" + }, + { + "id": "c", + "text": "A dessert worth sharing" + }, + { + "id": "d", + "text": "A thoughtful note" + }, + { + "id": "e", + "text": "A place with a view for this date" + } + ] } }, { "id": "date_night_120", "category_id": "date_night", - "type": "written", - "text": "What should our default date be when we cannot decide?", + "type": "multi_choice", + "text": "Select the pieces that fit a bigger date night:", "depth": 1, "access": "premium", "tags": [ - "default_date", - "ease" + "date_night", + "multi_choice", + "anniversary" + ], + "options": [ + { + "id": "a", + "text": "A place with a view with a twist" + }, + { + "id": "b", + "text": "Dressing up" + }, + { + "id": "c", + "text": "A thoughtful note for this date" + }, + { + "id": "d", + "text": "A slow dinner" + }, + { + "id": "e", + "text": "A photo we actually like for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A place with a view with a twist" + }, + { + "id": "b", + "text": "Dressing up" + }, + { + "id": "c", + "text": "A thoughtful note for this date" + }, + { + "id": "d", + "text": "A slow dinner" + }, + { + "id": "e", + "text": "A photo we actually like for this date" + } + ] } }, { "id": "date_night_121", "category_id": "date_night", - "type": "written", - "text": "What date would you want us to do every year?", - "depth": 2, + "type": "multi_choice", + "text": "Pick the comfort-date ideas we would actually choose:", + "depth": 1, "access": "premium", "tags": [ - "tradition", - "yearly" + "date_night", + "multi_choice", + "comfort" + ], + "options": [ + { + "id": "a", + "text": "Our usual order, but intentional" + }, + { + "id": "b", + "text": "A favorite movie with snacks" + }, + { + "id": "c", + "text": "A walk we know well" + }, + { + "id": "d", + "text": "Breakfast together" + }, + { + "id": "e", + "text": "A familiar restaurant" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Our usual order, but intentional" + }, + { + "id": "b", + "text": "A favorite movie with snacks" + }, + { + "id": "c", + "text": "A walk we know well" + }, + { + "id": "d", + "text": "Breakfast together" + }, + { + "id": "e", + "text": "A familiar restaurant" + } + ] } }, { "id": "date_night_122", "category_id": "date_night", - "type": "written", - "text": "What is a date idea that feels special to our relationship?", - "depth": 2, + "type": "multi_choice", + "text": "Which familiar plans still feel like a date?", + "depth": 1, "access": "premium", "tags": [ - "couple_identity", - "special" + "date_night", + "multi_choice", + "comfort" + ], + "options": [ + { + "id": "a", + "text": "Breakfast together" + }, + { + "id": "b", + "text": "A couch night with a start time" + }, + { + "id": "c", + "text": "A walk we know well" + }, + { + "id": "d", + "text": "Coffee from our place" + }, + { + "id": "e", + "text": "A familiar restaurant" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Breakfast together" + }, + { + "id": "b", + "text": "A couch night with a start time" + }, + { + "id": "c", + "text": "A walk we know well" + }, + { + "id": "d", + "text": "Coffee from our place" + }, + { + "id": "e", + "text": "A familiar restaurant" + } + ] } }, { "id": "date_night_123", "category_id": "date_night", - "type": "written", - "text": "What place or activity reminds you of us?", - "depth": 2, + "type": "multi_choice", + "text": "What comfort-date moves belong on our list?", + "depth": 1, "access": "premium", "tags": [ - "memories", - "identity" + "date_night", + "multi_choice", + "comfort" + ], + "options": [ + { + "id": "a", + "text": "A familiar restaurant" + }, + { + "id": "b", + "text": "A couch night with a start time" + }, + { + "id": "c", + "text": "Coffee from our place" + }, + { + "id": "d", + "text": "A dessert we already love" + }, + { + "id": "e", + "text": "Our usual order, but intentional" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A familiar restaurant" + }, + { + "id": "b", + "text": "A couch night with a start time" + }, + { + "id": "c", + "text": "Coffee from our place" + }, + { + "id": "d", + "text": "A dessert we already love" + }, + { + "id": "e", + "text": "Our usual order, but intentional" + } + ] } }, { "id": "date_night_124", "category_id": "date_night", - "type": "written", - "text": "What is one thing you want to remember from our next date?", - "depth": 2, + "type": "multi_choice", + "text": "Choose the reliable dates that never feel wrong:", + "depth": 1, "access": "premium", "tags": [ - "memories", - "next_date" + "date_night", + "multi_choice", + "comfort" + ], + "options": [ + { + "id": "a", + "text": "A dessert we already love" + }, + { + "id": "b", + "text": "A favorite movie with snacks" + }, + { + "id": "c", + "text": "Coffee from our place" + }, + { + "id": "d", + "text": "A walk we know well" + }, + { + "id": "e", + "text": "Our usual order, but intentional" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A dessert we already love" + }, + { + "id": "b", + "text": "A favorite movie with snacks" + }, + { + "id": "c", + "text": "Coffee from our place" + }, + { + "id": "d", + "text": "A walk we know well" + }, + { + "id": "e", + "text": "Our usual order, but intentional" + } + ] } }, { "id": "date_night_125", "category_id": "date_night", - "type": "written", - "text": "What do you want our dates to feel like in this stage of life?", - "depth": 3, + "type": "multi_choice", + "text": "Select the familiar ideas that still work:", + "depth": 1, "access": "premium", "tags": [ - "life_stage", - "date_night" + "date_night", + "multi_choice", + "comfort" + ], + "options": [ + { + "id": "a", + "text": "Our usual order, but intentional for this date" + }, + { + "id": "b", + "text": "A favorite movie with snacks" + }, + { + "id": "c", + "text": "A walk we know well for this date" + }, + { + "id": "d", + "text": "Breakfast together" + }, + { + "id": "e", + "text": "A familiar restaurant for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Our usual order, but intentional for this date" + }, + { + "id": "b", + "text": "A favorite movie with snacks" + }, + { + "id": "c", + "text": "A walk we know well for this date" + }, + { + "id": "d", + "text": "Breakfast together" + }, + { + "id": "e", + "text": "A familiar restaurant for this date" + } + ] } }, { "id": "date_night_126", "category_id": "date_night", - "type": "written", - "text": "What is something you miss about how we used to spend time together?", - "depth": 3, + "type": "multi_choice", + "text": "Pick the date settings that help us talk:", + "depth": 1, "access": "premium", "tags": [ - "missing", - "reflection" + "date_night", + "multi_choice", + "conversation" + ], + "options": [ + { + "id": "a", + "text": "A quiet table" + }, + { + "id": "b", + "text": "A long walk" + }, + { + "id": "c", + "text": "Coffee with no rush" + }, + { + "id": "d", + "text": "A scenic drive for this date" + }, + { + "id": "e", + "text": "A patio away from crowds" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A quiet table" + }, + { + "id": "b", + "text": "A long walk" + }, + { + "id": "c", + "text": "Coffee with no rush" + }, + { + "id": "d", + "text": "A scenic drive for this date" + }, + { + "id": "e", + "text": "A patio away from crowds" + } + ] } }, { "id": "date_night_127", "category_id": "date_night", - "type": "written", - "text": "What is something you like about how we spend time together now?", - "depth": 2, + "type": "multi_choice", + "text": "Which date ideas leave room for real conversation?", + "depth": 1, "access": "premium", "tags": [ - "gratitude", - "present" + "date_night", + "multi_choice", + "conversation" + ], + "options": [ + { + "id": "a", + "text": "A scenic drive with a twist" + }, + { + "id": "b", + "text": "A picnic bench" + }, + { + "id": "c", + "text": "Coffee with no rush" + }, + { + "id": "d", + "text": "A low-key bar" + }, + { + "id": "e", + "text": "A patio away from crowds" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A scenic drive with a twist" + }, + { + "id": "b", + "text": "A picnic bench" + }, + { + "id": "c", + "text": "Coffee with no rush" + }, + { + "id": "d", + "text": "A low-key bar" + }, + { + "id": "e", + "text": "A patio away from crowds" + } + ] } }, { "id": "date_night_128", "category_id": "date_night", - "type": "written", - "text": "What is one date idea that would help us feel young again?", - "depth": 2, + "type": "multi_choice", + "text": "What should we choose if talking is the point?", + "depth": 1, "access": "premium", "tags": [ - "playfulness", - "renewal" + "date_night", + "multi_choice", + "conversation" + ], + "options": [ + { + "id": "a", + "text": "A patio away from crowds" + }, + { + "id": "b", + "text": "A picnic bench" + }, + { + "id": "c", + "text": "A low-key bar" + }, + { + "id": "d", + "text": "A late breakfast" + }, + { + "id": "e", + "text": "A quiet table" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A patio away from crowds" + }, + { + "id": "b", + "text": "A picnic bench" + }, + { + "id": "c", + "text": "A low-key bar" + }, + { + "id": "d", + "text": "A late breakfast" + }, + { + "id": "e", + "text": "A quiet table" + } + ] } }, { "id": "date_night_129", "category_id": "date_night", - "type": "written", - "text": "What is a date idea that would help us feel peaceful?", - "depth": 2, + "type": "multi_choice", + "text": "Select the plans that make conversation easy:", + "depth": 1, "access": "premium", "tags": [ - "peace", - "date_idea" + "date_night", + "multi_choice", + "conversation" + ], + "options": [ + { + "id": "a", + "text": "A late breakfast" + }, + { + "id": "b", + "text": "A long walk for this date" + }, + { + "id": "c", + "text": "A low-key bar" + }, + { + "id": "d", + "text": "Coffee with no rush" + }, + { + "id": "e", + "text": "A quiet table for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A late breakfast" + }, + { + "id": "b", + "text": "A long walk for this date" + }, + { + "id": "c", + "text": "A low-key bar" + }, + { + "id": "d", + "text": "Coffee with no rush" + }, + { + "id": "e", + "text": "A quiet table for this date" + } + ] } }, { "id": "date_night_130", "category_id": "date_night", - "type": "written", - "text": "What is a date idea that would help us feel adventurous?", - "depth": 2, + "type": "multi_choice", + "text": "Choose date ideas where we can actually hear each other:", + "depth": 1, "access": "premium", "tags": [ - "adventure", - "date_idea" + "date_night", + "multi_choice", + "conversation" + ], + "options": [ + { + "id": "a", + "text": "A quiet table with a twist" + }, + { + "id": "b", + "text": "A long walk with a twist" + }, + { + "id": "c", + "text": "Coffee with no rush for this date" + }, + { + "id": "d", + "text": "A scenic drive somewhere new" + }, + { + "id": "e", + "text": "A patio away from crowds for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A quiet table with a twist" + }, + { + "id": "b", + "text": "A long walk with a twist" + }, + { + "id": "c", + "text": "Coffee with no rush for this date" + }, + { + "id": "d", + "text": "A scenic drive somewhere new" + }, + { + "id": "e", + "text": "A patio away from crowds for this date" + } + ] } }, { "id": "date_night_131", "category_id": "date_night", - "type": "written", - "text": "What is a date idea that would help us feel romantic?", - "depth": 2, + "type": "multi_choice", + "text": "Pick the food-date ideas that sound worth trying:", + "depth": 1, "access": "premium", "tags": [ - "romance", - "date_idea" + "date_night", + "multi_choice", + "food_adventure" + ], + "options": [ + { + "id": "a", + "text": "A dessert crawl" + }, + { + "id": "b", + "text": "A taco comparison" + }, + { + "id": "c", + "text": "A bakery morning" + }, + { + "id": "d", + "text": "A shared appetizer night" + }, + { + "id": "e", + "text": "A new brunch place" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A dessert crawl" + }, + { + "id": "b", + "text": "A taco comparison" + }, + { + "id": "c", + "text": "A bakery morning" + }, + { + "id": "d", + "text": "A shared appetizer night" + }, + { + "id": "e", + "text": "A new brunch place" + } + ] } }, { "id": "date_night_132", "category_id": "date_night", - "type": "written", - "text": "What is a date idea that would help us feel silly together?", + "type": "multi_choice", + "text": "Which food adventure belongs on the list?", "depth": 1, "access": "premium", "tags": [ - "silly", - "playfulness" + "date_night", + "multi_choice", + "food_adventure" + ], + "options": [ + { + "id": "a", + "text": "A shared appetizer night" + }, + { + "id": "b", + "text": "A dumpling or ramen stop" + }, + { + "id": "c", + "text": "A bakery morning" + }, + { + "id": "d", + "text": "A farmers market treat" + }, + { + "id": "e", + "text": "A new brunch place" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A shared appetizer night" + }, + { + "id": "b", + "text": "A dumpling or ramen stop" + }, + { + "id": "c", + "text": "A bakery morning" + }, + { + "id": "d", + "text": "A farmers market treat" + }, + { + "id": "e", + "text": "A new brunch place" + } + ] } }, { "id": "date_night_133", "category_id": "date_night", - "type": "written", - "text": "What is one new experience you want to share with me?", - "depth": 2, + "type": "multi_choice", + "text": "What should we taste-test together?", + "depth": 1, "access": "premium", "tags": [ - "new_things", - "shared_experience" + "date_night", + "multi_choice", + "food_adventure" + ], + "options": [ + { + "id": "a", + "text": "A new brunch place" + }, + { + "id": "b", + "text": "A dumpling or ramen stop" + }, + { + "id": "c", + "text": "A farmers market treat" + }, + { + "id": "d", + "text": "A make-at-home dinner theme" + }, + { + "id": "e", + "text": "A dessert crawl" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A new brunch place" + }, + { + "id": "b", + "text": "A dumpling or ramen stop" + }, + { + "id": "c", + "text": "A farmers market treat" + }, + { + "id": "d", + "text": "A make-at-home dinner theme" + }, + { + "id": "e", + "text": "A dessert crawl" + } + ] } }, { "id": "date_night_134", "category_id": "date_night", - "type": "written", - "text": "What would be a dream date if time and money were not a problem?", - "depth": 2, + "type": "multi_choice", + "text": "Choose the edible date plans that sound fun:", + "depth": 1, "access": "premium", "tags": [ - "dream_date", - "future" + "date_night", + "multi_choice", + "food_adventure" + ], + "options": [ + { + "id": "a", + "text": "A make-at-home dinner theme" + }, + { + "id": "b", + "text": "A taco comparison" + }, + { + "id": "c", + "text": "A farmers market treat" + }, + { + "id": "d", + "text": "A bakery morning" + }, + { + "id": "e", + "text": "A dessert crawl" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A make-at-home dinner theme" + }, + { + "id": "b", + "text": "A taco comparison" + }, + { + "id": "c", + "text": "A farmers market treat" + }, + { + "id": "d", + "text": "A bakery morning" + }, + { + "id": "e", + "text": "A dessert crawl" + } + ] } }, { "id": "date_night_135", "category_id": "date_night", - "type": "written", - "text": "What is a realistic dream date we could actually plan soon?", - "depth": 2, + "type": "multi_choice", + "text": "Select the food ideas we would both show up for:", + "depth": 1, "access": "premium", "tags": [ - "dream_date", - "planning" + "date_night", + "multi_choice", + "food_adventure" + ], + "options": [ + { + "id": "a", + "text": "A dessert crawl for this date" + }, + { + "id": "b", + "text": "A taco comparison" + }, + { + "id": "c", + "text": "A bakery morning for this date" + }, + { + "id": "d", + "text": "A shared appetizer night" + }, + { + "id": "e", + "text": "A new brunch place for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A dessert crawl for this date" + }, + { + "id": "b", + "text": "A taco comparison" + }, + { + "id": "c", + "text": "A bakery morning for this date" + }, + { + "id": "d", + "text": "A shared appetizer night" + }, + { + "id": "e", + "text": "A new brunch place for this date" + } + ] } }, { "id": "date_night_136", "category_id": "date_night", - "type": "written", - "text": "What is one date we should save up for?", - "depth": 2, + "type": "multi_choice", + "text": "Pick the ways to make the date feel less distracted:", + "depth": 1, "access": "premium", "tags": [ - "budget", - "future" + "date_night", + "multi_choice", + "phone_free" + ], + "options": [ + { + "id": "a", + "text": "Phones away during dinner" + }, + { + "id": "b", + "text": "One photo, then pockets" + }, + { + "id": "c", + "text": "Pick the movie first" + }, + { + "id": "d", + "text": "No work talk at the table" + }, + { + "id": "e", + "text": "A walk without scrolling" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Phones away during dinner" + }, + { + "id": "b", + "text": "One photo, then pockets" + }, + { + "id": "c", + "text": "Pick the movie first" + }, + { + "id": "d", + "text": "No work talk at the table" + }, + { + "id": "e", + "text": "A walk without scrolling" + } + ] } }, { "id": "date_night_137", "category_id": "date_night", - "type": "written", - "text": "What is one date you would like me to plan completely?", - "depth": 2, + "type": "multi_choice", + "text": "Which no-scroll details would help date night?", + "depth": 1, "access": "premium", "tags": [ - "planning", - "surprise" + "date_night", + "multi_choice", + "phone_free" + ], + "options": [ + { + "id": "a", + "text": "No work talk at the table" + }, + { + "id": "b", + "text": "A playlist before we start" + }, + { + "id": "c", + "text": "Pick the movie first" + }, + { + "id": "d", + "text": "A clear start time" + }, + { + "id": "e", + "text": "A walk without scrolling" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "No work talk at the table" + }, + { + "id": "b", + "text": "A playlist before we start" + }, + { + "id": "c", + "text": "Pick the movie first" + }, + { + "id": "d", + "text": "A clear start time" + }, + { + "id": "e", + "text": "A walk without scrolling" + } + ] } }, { "id": "date_night_138", "category_id": "date_night", - "type": "written", - "text": "What is one date you would rather plan together?", - "depth": 2, + "type": "multi_choice", + "text": "What should we do so the date gets our attention?", + "depth": 1, "access": "premium", "tags": [ - "planning", - "teamwork" + "date_night", + "multi_choice", + "phone_free" + ], + "options": [ + { + "id": "a", + "text": "A walk without scrolling" + }, + { + "id": "b", + "text": "A playlist before we start" + }, + { + "id": "c", + "text": "A clear start time" + }, + { + "id": "d", + "text": "A dessert stop after phones go away" + }, + { + "id": "e", + "text": "Phones away during dinner" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A walk without scrolling" + }, + { + "id": "b", + "text": "A playlist before we start" + }, + { + "id": "c", + "text": "A clear start time" + }, + { + "id": "d", + "text": "A dessert stop after phones go away" + }, + { + "id": "e", + "text": "Phones away during dinner" + } + ] } }, { "id": "date_night_139", "category_id": "date_night", - "type": "written", - "text": "What makes you feel comfortable saying what kind of date you want?", - "depth": 3, + "type": "multi_choice", + "text": "Choose the phone-light date rules that feel reasonable:", + "depth": 1, "access": "premium", "tags": [ - "communication", - "comfort" + "date_night", + "multi_choice", + "phone_free" + ], + "options": [ + { + "id": "a", + "text": "A dessert stop after phones go away" + }, + { + "id": "b", + "text": "One photo, then pockets" + }, + { + "id": "c", + "text": "A clear start time" + }, + { + "id": "d", + "text": "Pick the movie first" + }, + { + "id": "e", + "text": "Phones away during dinner" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A dessert stop after phones go away" + }, + { + "id": "b", + "text": "One photo, then pockets" + }, + { + "id": "c", + "text": "A clear start time" + }, + { + "id": "d", + "text": "Pick the movie first" + }, + { + "id": "e", + "text": "Phones away during dinner" + } + ] } }, { "id": "date_night_140", "category_id": "date_night", - "type": "written", - "text": "What do you wish I understood better about your idea of romance?", - "depth": 3, + "type": "multi_choice", + "text": "Select what would keep us present without making it weird:", + "depth": 1, "access": "premium", "tags": [ - "romance", - "understanding" + "date_night", + "multi_choice", + "phone_free" + ], + "options": [ + { + "id": "a", + "text": "Phones away during dinner for this date" + }, + { + "id": "b", + "text": "One photo, then pockets" + }, + { + "id": "c", + "text": "Pick the movie first for this date" + }, + { + "id": "d", + "text": "No work talk at the table" + }, + { + "id": "e", + "text": "A walk without scrolling for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Phones away during dinner for this date" + }, + { + "id": "b", + "text": "One photo, then pockets" + }, + { + "id": "c", + "text": "Pick the movie first for this date" + }, + { + "id": "d", + "text": "No work talk at the table" + }, + { + "id": "e", + "text": "A walk without scrolling for this date" + } + ] } }, { "id": "date_night_141", "category_id": "date_night", - "type": "written", - "text": "What do you wish I understood better about your idea of fun?", - "depth": 3, + "type": "multi_choice", + "text": "Pick the dress-up details that sound fun:", + "depth": 1, "access": "premium", "tags": [ - "fun", - "understanding" + "date_night", + "multi_choice", + "dress_up" + ], + "options": [ + { + "id": "a", + "text": "A nicer outfit" + }, + { + "id": "b", + "text": "A good photo before leaving" + }, + { + "id": "c", + "text": "A place that matches the outfit" + }, + { + "id": "d", + "text": "A scent we like" + }, + { + "id": "e", + "text": "Better shoes than usual" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A nicer outfit" + }, + { + "id": "b", + "text": "A good photo before leaving" + }, + { + "id": "c", + "text": "A place that matches the outfit" + }, + { + "id": "d", + "text": "A scent we like" + }, + { + "id": "e", + "text": "Better shoes than usual" + } + ] } }, { "id": "date_night_142", "category_id": "date_night", - "type": "written", - "text": "What is one way our dates could fit our real life better?", - "depth": 2, + "type": "multi_choice", + "text": "Which style choices would make date night feel different?", + "depth": 1, "access": "premium", "tags": [ - "real_life", - "ease" + "date_night", + "multi_choice", + "dress_up" + ], + "options": [ + { + "id": "a", + "text": "A scent we like" + }, + { + "id": "b", + "text": "A dinner that feels worth it" + }, + { + "id": "c", + "text": "A place that matches the outfit" + }, + { + "id": "d", + "text": "A compliment before we go" + }, + { + "id": "e", + "text": "Better shoes than usual" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A scent we like" + }, + { + "id": "b", + "text": "A dinner that feels worth it" + }, + { + "id": "c", + "text": "A place that matches the outfit" + }, + { + "id": "d", + "text": "A compliment before we go" + }, + { + "id": "e", + "text": "Better shoes than usual" + } + ] } }, { "id": "date_night_143", "category_id": "date_night", - "type": "written", - "text": "What would make date night feel less pressured and more natural?", - "depth": 2, + "type": "multi_choice", + "text": "What should we do if we want a dressed-up date?", + "depth": 1, "access": "premium", "tags": [ - "pressure", - "ease" + "date_night", + "multi_choice", + "dress_up" + ], + "options": [ + { + "id": "a", + "text": "Better shoes than usual" + }, + { + "id": "b", + "text": "A dinner that feels worth it" + }, + { + "id": "c", + "text": "A compliment before we go" + }, + { + "id": "d", + "text": "A reason to take our time" + }, + { + "id": "e", + "text": "A nicer outfit" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Better shoes than usual" + }, + { + "id": "b", + "text": "A dinner that feels worth it" + }, + { + "id": "c", + "text": "A compliment before we go" + }, + { + "id": "d", + "text": "A reason to take our time" + }, + { + "id": "e", + "text": "A nicer outfit" + } + ] } }, { "id": "date_night_144", "category_id": "date_night", - "type": "written", - "text": "What kind of date helps you feel loved without needing anything fancy?", - "depth": 3, + "type": "multi_choice", + "text": "Choose the date-night style moves that fit us:", + "depth": 1, "access": "premium", "tags": [ - "love", - "simple_dates" + "date_night", + "multi_choice", + "dress_up" + ], + "options": [ + { + "id": "a", + "text": "A reason to take our time" + }, + { + "id": "b", + "text": "A good photo before leaving" + }, + { + "id": "c", + "text": "A compliment before we go" + }, + { + "id": "d", + "text": "A place that matches the outfit" + }, + { + "id": "e", + "text": "A nicer outfit" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A reason to take our time" + }, + { + "id": "b", + "text": "A good photo before leaving" + }, + { + "id": "c", + "text": "A compliment before we go" + }, + { + "id": "d", + "text": "A place that matches the outfit" + }, + { + "id": "e", + "text": "A nicer outfit" + } + ] } }, { "id": "date_night_145", "category_id": "date_night", - "type": "written", - "text": "What is one date we could plan that would make this month feel better?", - "depth": 2, + "type": "multi_choice", + "text": "Select the details that make going out feel like an occasion:", + "depth": 1, "access": "premium", "tags": [ - "monthly", - "planning" + "date_night", + "multi_choice", + "dress_up" + ], + "options": [ + { + "id": "a", + "text": "A nicer outfit for this date" + }, + { + "id": "b", + "text": "A good photo before leaving" + }, + { + "id": "c", + "text": "A place that matches the outfit for this date" + }, + { + "id": "d", + "text": "A scent we like" + }, + { + "id": "e", + "text": "Better shoes than usual for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "A nicer outfit for this date" + }, + { + "id": "b", + "text": "A good photo before leaving" + }, + { + "id": "c", + "text": "A place that matches the outfit for this date" + }, + { + "id": "d", + "text": "A scent we like" + }, + { + "id": "e", + "text": "Better shoes than usual for this date" + } + ] } }, { "id": "date_night_146", "category_id": "date_night", - "type": "written", - "text": "What should we do more often because it is good for us?", + "type": "multi_choice", + "text": "Pick the date traditions worth keeping:", "depth": 2, "access": "premium", "tags": [ - "habits", - "connection" + "date_night", + "multi_choice", + "tradition" + ], + "options": [ + { + "id": "a", + "text": "Trying one new dessert" + }, + { + "id": "b", + "text": "Taking one photo" + }, + { + "id": "c", + "text": "A walk after dinner" + }, + { + "id": "d", + "text": "Alternating who plans" + }, + { + "id": "e", + "text": "Saving one place on a list" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Trying one new dessert" + }, + { + "id": "b", + "text": "Taking one photo" + }, + { + "id": "c", + "text": "A walk after dinner" + }, + { + "id": "d", + "text": "Alternating who plans" + }, + { + "id": "e", + "text": "Saving one place on a list" + } + ] } }, { "id": "date_night_147", "category_id": "date_night", - "type": "written", - "text": "What should we stop forcing if it never feels fun?", + "type": "multi_choice", + "text": "Which recurring date ideas should become ours?", "depth": 2, "access": "premium", "tags": [ - "honesty", - "preferences" + "date_night", + "multi_choice", + "tradition" + ], + "options": [ + { + "id": "a", + "text": "Alternating who plans" + }, + { + "id": "b", + "text": "Picking a song for the drive" + }, + { + "id": "c", + "text": "A walk after dinner" + }, + { + "id": "d", + "text": "A favorite booth if we can get it" + }, + { + "id": "e", + "text": "Saving one place on a list" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Alternating who plans" + }, + { + "id": "b", + "text": "Picking a song for the drive" + }, + { + "id": "c", + "text": "A walk after dinner" + }, + { + "id": "d", + "text": "A favorite booth if we can get it" + }, + { + "id": "e", + "text": "Saving one place on a list" + } + ] } }, { "id": "date_night_148", "category_id": "date_night", - "type": "written", - "text": "What is one thing we could try once and never do again if we hate it?", - "depth": 1, + "type": "multi_choice", + "text": "What date habit would be nice to repeat?", + "depth": 2, "access": "premium", "tags": [ - "new_things", - "low_pressure" + "date_night", + "multi_choice", + "tradition" + ], + "options": [ + { + "id": "a", + "text": "Saving one place on a list" + }, + { + "id": "b", + "text": "Picking a song for the drive" + }, + { + "id": "c", + "text": "A favorite booth if we can get it" + }, + { + "id": "d", + "text": "Ending with coffee or tea" + }, + { + "id": "e", + "text": "Trying one new dessert" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Saving one place on a list" + }, + { + "id": "b", + "text": "Picking a song for the drive" + }, + { + "id": "c", + "text": "A favorite booth if we can get it" + }, + { + "id": "d", + "text": "Ending with coffee or tea" + }, + { + "id": "e", + "text": "Trying one new dessert" + } + ] } }, { "id": "date_night_149", "category_id": "date_night", - "type": "written", - "text": "What date would help us celebrate something small?", + "type": "multi_choice", + "text": "Choose the traditions that sound like us:", "depth": 2, "access": "premium", "tags": [ - "celebration", - "date_idea" + "date_night", + "multi_choice", + "tradition" + ], + "options": [ + { + "id": "a", + "text": "Ending with coffee or tea" + }, + { + "id": "b", + "text": "Taking one photo" + }, + { + "id": "c", + "text": "A favorite booth if we can get it" + }, + { + "id": "d", + "text": "A walk after dinner" + }, + { + "id": "e", + "text": "Trying one new dessert" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Ending with coffee or tea" + }, + { + "id": "b", + "text": "Taking one photo" + }, + { + "id": "c", + "text": "A favorite booth if we can get it" + }, + { + "id": "d", + "text": "A walk after dinner" + }, + { + "id": "e", + "text": "Trying one new dessert" + } + ] } }, { "id": "date_night_150", "category_id": "date_night", - "type": "written", - "text": "What date would help us mark a fresh start?", - "depth": 3, + "type": "multi_choice", + "text": "Select anything that could become our date-night thing:", + "depth": 2, "access": "premium", "tags": [ - "fresh_start", - "renewal" + "date_night", + "multi_choice", + "tradition" + ], + "options": [ + { + "id": "a", + "text": "Trying one new dessert for this date" + }, + { + "id": "b", + "text": "Taking one photo" + }, + { + "id": "c", + "text": "A walk after dinner for this date" + }, + { + "id": "d", + "text": "Alternating who plans" + }, + { + "id": "e", + "text": "Saving one place on a list for this date" + } ], "answer_config": { - "min_length": 1, - "max_length": 1000, - "placeholder": "Write your answer..." + "options": [ + { + "id": "a", + "text": "Trying one new dessert for this date" + }, + { + "id": "b", + "text": "Taking one photo" + }, + { + "id": "c", + "text": "A walk after dinner for this date" + }, + { + "id": "d", + "text": "Alternating who plans" + }, + { + "id": "e", + "text": "Saving one place on a list for this date" + } + ] } }, { "id": "date_night_151", "category_id": "date_night", - "type": "single_choice", - "text": "Which kind of date sounds best this week?", - "depth": 1, - "access": "free", - "tags": [ - "preference", - "weekly" - ], - "options": [ - { - "id": "cozy_at_home", - "text": "Cozy at home" - }, - { - "id": "dinner_out", - "text": "Dinner out" - }, - { - "id": "something_playful", - "text": "Something playful" - }, - { - "id": "something_outside", - "text": "Something outside" - }, - { - "id": "surprise_me", - "text": "Surprise me" - } - ] - }, - { - "id": "date_night_152", - "category_id": "date_night", - "type": "single_choice", - "text": "What pace sounds best for our next date?", - "depth": 1, - "access": "free", - "tags": [ - "pace", - "preference" - ], - "options": [ - { - "id": "slow_and_easy", - "text": "Slow and easy" - }, - { - "id": "fun_and_active", - "text": "Fun and active" - }, - { - "id": "short_and_sweet", - "text": "Short and sweet" - }, - { - "id": "all_evening", - "text": "All evening" - }, - { - "id": "not_sure", - "text": "Not sure yet" - } - ] - }, - { - "id": "date_night_153", - "category_id": "date_night", - "type": "single_choice", - "text": "Which food plan sounds best?", - "depth": 1, - "access": "free", - "tags": [ - "food", - "planning" - ], - "options": [ - { - "id": "cook_together", - "text": "Cook together" - }, - { - "id": "order_in", - "text": "Order in" - }, - { - "id": "try_new_place", - "text": "Try a new place" - }, - { - "id": "dessert_only", - "text": "Dessert only" - }, - { - "id": "coffee_or_breakfast", - "text": "Coffee or breakfast" - } - ] - }, - { - "id": "date_night_154", - "category_id": "date_night", - "type": "single_choice", - "text": "What would make a home date feel special?", - "depth": 1, - "access": "free", - "tags": [ - "home_date", - "special" - ], - "options": [ - { - "id": "music", - "text": "Music" - }, - { - "id": "favorite_food", - "text": "Favorite food" - }, - { - "id": "phones_away", - "text": "Phones away" - }, - { - "id": "clean_space", - "text": "Clean space" - }, - { - "id": "a_game", - "text": "A game" - } - ] - }, - { - "id": "date_night_155", - "category_id": "date_night", - "type": "single_choice", - "text": "What kind of date feels easiest right now?", - "depth": 1, - "access": "free", - "tags": [ - "easy_dates", - "preference" - ], - "options": [ - { - "id": "walk", - "text": "A walk" - }, - { - "id": "movie_night", - "text": "Movie night" - }, - { - "id": "coffee", - "text": "Coffee" - }, - { - "id": "takeout", - "text": "Takeout" - }, - { - "id": "drive", - "text": "A drive" - } - ] - }, - { - "id": "date_night_156", - "category_id": "date_night", - "type": "single_choice", - "text": "What should our next date focus on most?", - "depth": 2, - "access": "free", - "tags": [ - "focus", - "next_date" - ], - "options": [ - { - "id": "rest", - "text": "Rest" - }, - { - "id": "fun", - "text": "Fun" - }, - { - "id": "romance", - "text": "Romance" - }, - { - "id": "conversation", - "text": "Conversation" - }, - { - "id": "trying_something_new", - "text": "Trying something new" - } - ] - }, - { - "id": "date_night_157", - "category_id": "date_night", - "type": "single_choice", - "text": "What would help you look forward to date night?", - "depth": 2, - "access": "free", - "tags": [ - "anticipation", - "support" - ], - "options": [ - { - "id": "clear_plan", - "text": "A clear plan" - }, - { - "id": "low_pressure", - "text": "Low pressure" - }, - { - "id": "thoughtful_detail", - "text": "A thoughtful detail" - }, - { - "id": "enough_notice", - "text": "Enough notice" - }, - { - "id": "shared_planning", - "text": "Planning together" - } - ] - }, - { - "id": "date_night_158", - "category_id": "date_night", - "type": "single_choice", - "text": "Which date-night mood sounds best tonight?", - "depth": 1, - "access": "free", - "tags": [ - "mood", - "tonight" - ], - "options": [ - { - "id": "sweet", - "text": "Sweet" - }, - { - "id": "silly", - "text": "Silly" - }, - { - "id": "peaceful", - "text": "Peaceful" - }, - { - "id": "flirty", - "text": "Flirty" - }, - { - "id": "adventurous", - "text": "Adventurous" - } - ] - }, - { - "id": "date_night_159", - "category_id": "date_night", - "type": "single_choice", - "text": "What usually makes a date feel thoughtful to you?", - "depth": 2, - "access": "free", - "tags": [ - "thoughtful", - "preference" - ], - "options": [ - { - "id": "remembering_preferences", - "text": "Remembering my preferences" - }, - { - "id": "planning_ahead", - "text": "Planning ahead" - }, - { - "id": "little_surprises", - "text": "Little surprises" - }, - { - "id": "full_attention", - "text": "Full attention" - }, - { - "id": "kind_words", - "text": "Kind words" - } - ] - }, - { - "id": "date_night_160", - "category_id": "date_night", - "type": "single_choice", - "text": "What is the best backup plan when date night falls apart?", - "depth": 1, - "access": "free", - "tags": [ - "backup_plan", - "flexibility" - ], - "options": [ - { - "id": "movie_at_home", - "text": "Movie at home" - }, - { - "id": "late_dessert", - "text": "Late dessert" - }, - { - "id": "short_walk", - "text": "Short walk" - }, - { - "id": "rain_check", - "text": "Rain check" - }, - { - "id": "couch_time", - "text": "Couch time" - } - ] - }, - { - "id": "date_night_161", - "category_id": "date_night", - "type": "single_choice", - "text": "How should we choose our next date?", - "depth": 1, - "access": "premium", - "tags": [ - "planning", - "choice" - ], - "options": [ - { - "id": "take_turns", - "text": "Take turns" - }, - { - "id": "pick_from_a_list", - "text": "Pick from a list" - }, - { - "id": "spin_the_wheel", - "text": "Spin the wheel" - }, - { - "id": "plan_together", - "text": "Plan together" - }, - { - "id": "surprise_each_other", - "text": "Surprise each other" - } - ] - }, - { - "id": "date_night_162", - "category_id": "date_night", - "type": "single_choice", - "text": "What kind of place makes conversation easiest?", + "type": "multi_choice", + "text": "Pick the bigger date ideas worth saving:", "depth": 2, "access": "premium", "tags": [ - "conversation", - "location" - ], - "options": [ - { - "id": "quiet_restaurant", - "text": "Quiet restaurant" - }, - { - "id": "coffee_shop", - "text": "Coffee shop" - }, - { - "id": "park_or_walk", - "text": "Park or walk" - }, - { - "id": "car_ride", - "text": "Car ride" - }, - { - "id": "home", - "text": "Home" - } - ] - }, - { - "id": "date_night_163", - "category_id": "date_night", - "type": "single_choice", - "text": "What should we put away first on date night?", - "depth": 2, - "access": "premium", - "tags": [ - "presence", - "distractions" - ], - "options": [ - { - "id": "phones", - "text": "Phones" - }, - { - "id": "work_talk", - "text": "Work talk" - }, - { - "id": "chores", - "text": "Chores" - }, - { - "id": "tv_background_noise", - "text": "Background TV" - }, - { - "id": "stressful_topics", - "text": "Stressful topics" - } - ] - }, - { - "id": "date_night_164", - "category_id": "date_night", - "type": "single_choice", - "text": "Which small gesture would mean the most on a date?", - "depth": 2, - "access": "premium", - "tags": [ - "gesture", - "romance" - ], - "options": [ - { - "id": "holding_hands", - "text": "Holding hands" - }, - { - "id": "a_sweet_note", - "text": "A sweet note" - }, - { - "id": "a_compliment", - "text": "A compliment" - }, - { - "id": "planning_something", - "text": "Planning something" - }, - { - "id": "checking_in", - "text": "Checking in" - } - ] - }, - { - "id": "date_night_165", - "category_id": "date_night", - "type": "single_choice", - "text": "What kind of surprise date would you enjoy most?", - "depth": 2, - "access": "premium", - "tags": [ - "surprise", - "preference" - ], - "options": [ - { - "id": "food_surprise", - "text": "Food surprise" - }, - { - "id": "activity_surprise", - "text": "Activity surprise" - }, - { - "id": "quiet_surprise", - "text": "Quiet surprise" - }, - { - "id": "romantic_surprise", - "text": "Romantic surprise" - }, - { - "id": "no_surprises", - "text": "No surprises" - } - ] - }, - { - "id": "date_night_166", - "category_id": "date_night", - "type": "single_choice", - "text": "What makes a date feel romantic without being too much?", - "depth": 2, - "access": "premium", - "tags": [ - "romance", - "comfort" - ], - "options": [ - { - "id": "soft_lighting", - "text": "Soft lighting" - }, - { - "id": "slow_conversation", - "text": "Slow conversation" - }, - { - "id": "thoughtful_words", - "text": "Thoughtful words" - }, - { - "id": "dressing_up", - "text": "Dressing up" - }, - { - "id": "affection", - "text": "Affection" - } - ] - }, - { - "id": "date_night_167", - "category_id": "date_night", - "type": "single_choice", - "text": "What makes a date feel playful?", - "depth": 1, - "access": "premium", - "tags": [ - "playfulness", - "date" - ], - "options": [ - { - "id": "a_game", - "text": "A game" - }, - { - "id": "a_silly_theme", - "text": "A silly theme" - }, - { - "id": "friendly_competition", - "text": "Friendly competition" - }, - { - "id": "trying_something_new", - "text": "Trying something new" - }, - { - "id": "laughing_at_ourselves", - "text": "Laughing at ourselves" - } - ] - }, - { - "id": "date_night_168", - "category_id": "date_night", - "type": "single_choice", - "text": "What helps a date feel relaxed?", - "depth": 1, - "access": "premium", - "tags": [ - "relaxation", - "date" - ], - "options": [ - { - "id": "no_rushing", - "text": "No rushing" - }, - { - "id": "comfortable_clothes", - "text": "Comfortable clothes" - }, - { - "id": "simple_plan", - "text": "A simple plan" - }, - { - "id": "quiet_place", - "text": "A quiet place" - }, - { - "id": "nothing_afterward", - "text": "Nothing afterward" - } - ] - }, - { - "id": "date_night_169", - "category_id": "date_night", - "type": "single_choice", - "text": "What would make date planning feel fair?", - "depth": 2, - "access": "premium", - "tags": [ - "planning", - "fairness" - ], - "options": [ - { - "id": "taking_turns", - "text": "Taking turns" - }, - { - "id": "sharing_ideas", - "text": "Sharing ideas" - }, - { - "id": "setting_budget", - "text": "Setting a budget" - }, - { - "id": "planning_together", - "text": "Planning together" - }, - { - "id": "keeping_it_simple", - "text": "Keeping it simple" - } - ] - }, - { - "id": "date_night_170", - "category_id": "date_night", - "type": "single_choice", - "text": "What conversation style do you want on our next date?", - "depth": 2, - "access": "premium", - "tags": [ - "conversation", - "style" - ], - "options": [ - { - "id": "light_and_fun", - "text": "Light and fun" - }, - { - "id": "deep_and_slow", - "text": "Deep and slow" - }, - { - "id": "mostly_catching_up", - "text": "Mostly catching up" - }, - { - "id": "dreaming_together", - "text": "Dreaming together" - }, - { - "id": "quiet_company", - "text": "Quiet company" - } - ] - }, - { - "id": "date_night_171", - "category_id": "date_night", - "type": "single_choice", - "text": "What should we avoid on a date when we are already tired?", - "depth": 2, - "access": "premium", - "tags": [ - "tired", - "boundaries" - ], - "options": [ - { - "id": "crowded_places", - "text": "Crowded places" - }, - { - "id": "big_decisions", - "text": "Big decisions" - }, - { - "id": "long_drives", - "text": "Long drives" - }, - { - "id": "heavy_topics", - "text": "Heavy topics" - }, - { - "id": "overplanning", - "text": "Overplanning" - } - ] - }, - { - "id": "date_night_172", - "category_id": "date_night", - "type": "single_choice", - "text": "What kind of date helps us reconnect after distance?", - "depth": 3, - "access": "premium", - "tags": [ - "reconnect", - "distance" - ], - "options": [ - { - "id": "quiet_walk", - "text": "Quiet walk" - }, - { - "id": "dinner_and_talk", - "text": "Dinner and talk" - }, - { - "id": "shared_activity", - "text": "Shared activity" - }, - { - "id": "cozy_night_in", - "text": "Cozy night in" - }, - { - "id": "something_new", - "text": "Something new" - } - ] - }, - { - "id": "date_night_173", - "category_id": "date_night", - "type": "single_choice", - "text": "What makes you feel most wanted on a date?", - "depth": 3, - "access": "premium", - "tags": [ - "feeling_wanted", - "romance" - ], - "options": [ - { - "id": "full_attention", - "text": "Full attention" - }, - { - "id": "planned_details", - "text": "Planned details" - }, - { - "id": "affection", - "text": "Affection" - }, - { - "id": "flirting", - "text": "Flirting" - }, - { - "id": "meaningful_words", - "text": "Meaningful words" - } - ] - }, - { - "id": "date_night_174", - "category_id": "date_night", - "type": "single_choice", - "text": "What would make a date feel personal to you?", - "depth": 2, - "access": "premium", - "tags": [ - "personal", - "thoughtful" - ], - "options": [ - { - "id": "favorite_food", - "text": "Favorite food" - }, - { - "id": "favorite_place", - "text": "Favorite place" - }, - { - "id": "inside_joke", - "text": "Inside joke" - }, - { - "id": "meaningful_music", - "text": "Meaningful music" - }, - { - "id": "something_i_mentioned", - "text": "Something I mentioned" - } - ] - }, - { - "id": "date_night_175", - "category_id": "date_night", - "type": "single_choice", - "text": "What is the easiest way to start date night well?", - "depth": 1, - "access": "premium", - "tags": [ - "start", - "date_night" - ], - "options": [ - { - "id": "kind_greeting", - "text": "Kind greeting" - }, - { - "id": "phones_away", - "text": "Phones away" - }, - { - "id": "small_compliment", - "text": "Small compliment" - }, - { - "id": "clear_plan", - "text": "Clear plan" - }, - { - "id": "hug_first", - "text": "Hug first" - } - ] - }, - { - "id": "date_night_176", - "category_id": "date_night", - "type": "single_choice", - "text": "What would make an outside date better?", - "depth": 1, - "access": "premium", - "tags": [ - "outside", - "date" - ], - "options": [ - { - "id": "good_weather", - "text": "Good weather" - }, - { - "id": "pretty_view", - "text": "Pretty view" - }, - { - "id": "snacks", - "text": "Snacks" - }, - { - "id": "comfortable_shoes", - "text": "Comfortable shoes" - }, - { - "id": "time_to_wander", - "text": "Time to wander" - } - ] - }, - { - "id": "date_night_177", - "category_id": "date_night", - "type": "single_choice", - "text": "What would make a movie night better?", - "depth": 1, - "access": "premium", - "tags": [ - "movie_night", - "home_date" - ], - "options": [ - { - "id": "good_snacks", - "text": "Good snacks" - }, - { - "id": "blankets", - "text": "Blankets" - }, - { - "id": "phones_away", - "text": "Phones away" - }, - { - "id": "choosing_together", - "text": "Choosing together" - }, - { - "id": "talk_after", - "text": "Talking after" - } - ] - }, - { - "id": "date_night_178", - "category_id": "date_night", - "type": "single_choice", - "text": "What kind of date should we save for?", - "depth": 2, - "access": "premium", - "tags": [ - "saving", + "date_night", + "multi_choice", "future" ], "options": [ { - "id": "concert", - "text": "Concert" + "id": "a", + "text": "A weekend day trip" }, { - "id": "weekend_trip", - "text": "Weekend trip" + "id": "b", + "text": "A dressed-up dinner" }, { - "id": "fancy_dinner", - "text": "Fancy dinner" + "id": "c", + "text": "A concert or show" }, { - "id": "class_or_workshop", - "text": "Class or workshop" + "id": "d", + "text": "A museum day" }, { - "id": "special_event", - "text": "Special event" + "id": "e", + "text": "A picnic somewhere pretty" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A weekend day trip" + }, + { + "id": "b", + "text": "A dressed-up dinner" + }, + { + "id": "c", + "text": "A concert or show" + }, + { + "id": "d", + "text": "A museum day" + }, + { + "id": "e", + "text": "A picnic somewhere pretty" + } + ] + } + }, + { + "id": "date_night_152", + "category_id": "date_night", + "type": "multi_choice", + "text": "Which future dates should make the list?", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "future" + ], + "options": [ + { + "id": "a", + "text": "A museum day" + }, + { + "id": "b", + "text": "A cooking class" + }, + { + "id": "c", + "text": "A concert or show" + }, + { + "id": "d", + "text": "A hotel night nearby" + }, + { + "id": "e", + "text": "A picnic somewhere pretty" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A museum day" + }, + { + "id": "b", + "text": "A cooking class" + }, + { + "id": "c", + "text": "A concert or show" + }, + { + "id": "d", + "text": "A hotel night nearby" + }, + { + "id": "e", + "text": "A picnic somewhere pretty" + } + ] + } + }, + { + "id": "date_night_153", + "category_id": "date_night", + "type": "multi_choice", + "text": "What should we plan when we have more time?", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "future" + ], + "options": [ + { + "id": "a", + "text": "A picnic somewhere pretty" + }, + { + "id": "b", + "text": "A cooking class" + }, + { + "id": "c", + "text": "A hotel night nearby" + }, + { + "id": "d", + "text": "A long breakfast date" + }, + { + "id": "e", + "text": "A weekend day trip" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A picnic somewhere pretty" + }, + { + "id": "b", + "text": "A cooking class" + }, + { + "id": "c", + "text": "A hotel night nearby" + }, + { + "id": "d", + "text": "A long breakfast date" + }, + { + "id": "e", + "text": "A weekend day trip" + } + ] + } + }, + { + "id": "date_night_154", + "category_id": "date_night", + "type": "multi_choice", + "text": "Choose the date ideas that deserve a calendar spot:", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "future" + ], + "options": [ + { + "id": "a", + "text": "A long breakfast date" + }, + { + "id": "b", + "text": "A dressed-up dinner for this date" + }, + { + "id": "c", + "text": "A hotel night nearby" + }, + { + "id": "d", + "text": "A concert or show" + }, + { + "id": "e", + "text": "A weekend day trip" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A long breakfast date" + }, + { + "id": "b", + "text": "A dressed-up dinner for this date" + }, + { + "id": "c", + "text": "A hotel night nearby" + }, + { + "id": "d", + "text": "A concert or show" + }, + { + "id": "e", + "text": "A weekend day trip" + } + ] + } + }, + { + "id": "date_night_155", + "category_id": "date_night", + "type": "multi_choice", + "text": "Select the plans we should stop vaguely mentioning:", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "future" + ], + "options": [ + { + "id": "a", + "text": "A weekend day trip for this date" + }, + { + "id": "b", + "text": "A dressed-up dinner with a twist" + }, + { + "id": "c", + "text": "A concert or show for this date" + }, + { + "id": "d", + "text": "A museum day" + }, + { + "id": "e", + "text": "A picnic somewhere pretty for this date" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A weekend day trip for this date" + }, + { + "id": "b", + "text": "A dressed-up dinner with a twist" + }, + { + "id": "c", + "text": "A concert or show for this date" + }, + { + "id": "d", + "text": "A museum day" + }, + { + "id": "e", + "text": "A picnic somewhere pretty for this date" + } + ] + } + }, + { + "id": "date_night_156", + "category_id": "date_night", + "type": "multi_choice", + "text": "Pick the explore-the-town dates that sound good:", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "explore" + ], + "options": [ + { + "id": "a", + "text": "A neighborhood we rarely visit" + }, + { + "id": "b", + "text": "A new coffee place" + }, + { + "id": "c", + "text": "A local market" + }, + { + "id": "d", + "text": "A restaurant with a patio" + }, + { + "id": "e", + "text": "A small event downtown" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A neighborhood we rarely visit" + }, + { + "id": "b", + "text": "A new coffee place" + }, + { + "id": "c", + "text": "A local market" + }, + { + "id": "d", + "text": "A restaurant with a patio" + }, + { + "id": "e", + "text": "A small event downtown" + } + ] + } + }, + { + "id": "date_night_157", + "category_id": "date_night", + "type": "multi_choice", + "text": "Which local date ideas should we try?", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "explore" + ], + "options": [ + { + "id": "a", + "text": "A restaurant with a patio" + }, + { + "id": "b", + "text": "A pretty lookout" + }, + { + "id": "c", + "text": "A local market" + }, + { + "id": "d", + "text": "A bookstore or record shop" + }, + { + "id": "e", + "text": "A small event downtown" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A restaurant with a patio" + }, + { + "id": "b", + "text": "A pretty lookout" + }, + { + "id": "c", + "text": "A local market" + }, + { + "id": "d", + "text": "A bookstore or record shop" + }, + { + "id": "e", + "text": "A small event downtown" + } + ] + } + }, + { + "id": "date_night_158", + "category_id": "date_night", + "type": "multi_choice", + "text": "What nearby plan feels worth leaving for?", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "explore" + ], + "options": [ + { + "id": "a", + "text": "A small event downtown" + }, + { + "id": "b", + "text": "A pretty lookout" + }, + { + "id": "c", + "text": "A bookstore or record shop" + }, + { + "id": "d", + "text": "A dessert place across town" + }, + { + "id": "e", + "text": "A neighborhood we rarely visit" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A small event downtown" + }, + { + "id": "b", + "text": "A pretty lookout" + }, + { + "id": "c", + "text": "A bookstore or record shop" + }, + { + "id": "d", + "text": "A dessert place across town" + }, + { + "id": "e", + "text": "A neighborhood we rarely visit" + } + ] + } + }, + { + "id": "date_night_159", + "category_id": "date_night", + "type": "multi_choice", + "text": "Choose the small adventure dates that fit us:", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "explore" + ], + "options": [ + { + "id": "a", + "text": "A dessert place across town" + }, + { + "id": "b", + "text": "A new coffee place" + }, + { + "id": "c", + "text": "A bookstore or record shop" + }, + { + "id": "d", + "text": "A local market" + }, + { + "id": "e", + "text": "A neighborhood we rarely visit" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A dessert place across town" + }, + { + "id": "b", + "text": "A new coffee place" + }, + { + "id": "c", + "text": "A bookstore or record shop" + }, + { + "id": "d", + "text": "A local market" + }, + { + "id": "e", + "text": "A neighborhood we rarely visit" + } + ] + } + }, + { + "id": "date_night_160", + "category_id": "date_night", + "type": "multi_choice", + "text": "Select the local spots that belong on the list:", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "explore" + ], + "options": [ + { + "id": "a", + "text": "A neighborhood we rarely visit for this date" + }, + { + "id": "b", + "text": "A new coffee place" + }, + { + "id": "c", + "text": "A local market for this date" + }, + { + "id": "d", + "text": "A restaurant with a patio" + }, + { + "id": "e", + "text": "A small event downtown for this date" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A neighborhood we rarely visit for this date" + }, + { + "id": "b", + "text": "A new coffee place" + }, + { + "id": "c", + "text": "A local market for this date" + }, + { + "id": "d", + "text": "A restaurant with a patio" + }, + { + "id": "e", + "text": "A small event downtown for this date" + } + ] + } + }, + { + "id": "date_night_161", + "category_id": "date_night", + "type": "multi_choice", + "text": "Pick the first-date energy we should bring back:", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "first_date_energy" + ], + "options": [ + { + "id": "a", + "text": "Getting ready with effort" + }, + { + "id": "b", + "text": "Asking better questions" + }, + { + "id": "c", + "text": "Choosing a place carefully" + }, + { + "id": "d", + "text": "A longer goodbye" + }, + { + "id": "e", + "text": "A little nervous flirting" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "Getting ready with effort" + }, + { + "id": "b", + "text": "Asking better questions" + }, + { + "id": "c", + "text": "Choosing a place carefully" + }, + { + "id": "d", + "text": "A longer goodbye" + }, + { + "id": "e", + "text": "A little nervous flirting" + } + ] + } + }, + { + "id": "date_night_162", + "category_id": "date_night", + "type": "multi_choice", + "text": "Which early-date details would still work on us?", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "first_date_energy" + ], + "options": [ + { + "id": "a", + "text": "A longer goodbye" + }, + { + "id": "b", + "text": "A planned pickup time" + }, + { + "id": "c", + "text": "Choosing a place carefully" + }, + { + "id": "d", + "text": "A photo before the date" + }, + { + "id": "e", + "text": "A little nervous flirting" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A longer goodbye" + }, + { + "id": "b", + "text": "A planned pickup time" + }, + { + "id": "c", + "text": "Choosing a place carefully" + }, + { + "id": "d", + "text": "A photo before the date" + }, + { + "id": "e", + "text": "A little nervous flirting" + } + ] + } + }, + { + "id": "date_night_163", + "category_id": "date_night", + "type": "multi_choice", + "text": "What should we borrow from when dating felt new?", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "first_date_energy" + ], + "options": [ + { + "id": "a", + "text": "A little nervous flirting" + }, + { + "id": "b", + "text": "A planned pickup time" + }, + { + "id": "c", + "text": "A photo before the date" + }, + { + "id": "d", + "text": "A follow-up message after" + }, + { + "id": "e", + "text": "Getting ready with effort" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A little nervous flirting" + }, + { + "id": "b", + "text": "A planned pickup time" + }, + { + "id": "c", + "text": "A photo before the date" + }, + { + "id": "d", + "text": "A follow-up message after" + }, + { + "id": "e", + "text": "Getting ready with effort" + } + ] + } + }, + { + "id": "date_night_164", + "category_id": "date_night", + "type": "multi_choice", + "text": "Choose the parts of early dating worth repeating:", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "first_date_energy" + ], + "options": [ + { + "id": "a", + "text": "A follow-up message after" + }, + { + "id": "b", + "text": "Asking better questions" + }, + { + "id": "c", + "text": "A photo before the date" + }, + { + "id": "d", + "text": "Choosing a place carefully" + }, + { + "id": "e", + "text": "Getting ready with effort" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A follow-up message after" + }, + { + "id": "b", + "text": "Asking better questions" + }, + { + "id": "c", + "text": "A photo before the date" + }, + { + "id": "d", + "text": "Choosing a place carefully" + }, + { + "id": "e", + "text": "Getting ready with effort" + } + ] + } + }, + { + "id": "date_night_165", + "category_id": "date_night", + "type": "multi_choice", + "text": "Select anything that would bring back new-date energy:", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "first_date_energy" + ], + "options": [ + { + "id": "a", + "text": "Getting ready with effort for this date" + }, + { + "id": "b", + "text": "Asking better questions" + }, + { + "id": "c", + "text": "Choosing a place carefully for this date" + }, + { + "id": "d", + "text": "A longer goodbye" + }, + { + "id": "e", + "text": "A little nervous flirting for this date" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "Getting ready with effort for this date" + }, + { + "id": "b", + "text": "Asking better questions" + }, + { + "id": "c", + "text": "Choosing a place carefully for this date" + }, + { + "id": "d", + "text": "A longer goodbye" + }, + { + "id": "e", + "text": "A little nervous flirting for this date" + } + ] + } + }, + { + "id": "date_night_166", + "category_id": "date_night", + "type": "multi_choice", + "text": "Pick the little luxuries that would upgrade date night:", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "little_luxury" + ], + "options": [ + { + "id": "a", + "text": "Better dessert" + }, + { + "id": "b", + "text": "Good seats" + }, + { + "id": "c", + "text": "A ride instead of parking stress" + }, + { + "id": "d", + "text": "A prettier table" + }, + { + "id": "e", + "text": "A drink somewhere nice" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "Better dessert" + }, + { + "id": "b", + "text": "Good seats" + }, + { + "id": "c", + "text": "A ride instead of parking stress" + }, + { + "id": "d", + "text": "A prettier table" + }, + { + "id": "e", + "text": "A drink somewhere nice" + } + ] + } + }, + { + "id": "date_night_167", + "category_id": "date_night", + "type": "multi_choice", + "text": "Which small splurges feel worth it?", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "little_luxury" + ], + "options": [ + { + "id": "a", + "text": "A prettier table" + }, + { + "id": "b", + "text": "A small flower stop for this date" + }, + { + "id": "c", + "text": "A ride instead of parking stress" + }, + { + "id": "d", + "text": "A shared appetizer before dessert" + }, + { + "id": "e", + "text": "A drink somewhere nice" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A prettier table" + }, + { + "id": "b", + "text": "A small flower stop for this date" + }, + { + "id": "c", + "text": "A ride instead of parking stress" + }, + { + "id": "d", + "text": "A shared appetizer before dessert" + }, + { + "id": "e", + "text": "A drink somewhere nice" + } + ] + } + }, + { + "id": "date_night_168", + "category_id": "date_night", + "type": "multi_choice", + "text": "What tiny upgrade would make the date better?", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "little_luxury" + ], + "options": [ + { + "id": "a", + "text": "A drink somewhere nice" + }, + { + "id": "b", + "text": "A small flower stop with a twist" + }, + { + "id": "c", + "text": "A shared appetizer after dinner" + }, + { + "id": "d", + "text": "A later checkout of the night" + }, + { + "id": "e", + "text": "Better dessert" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A drink somewhere nice" + }, + { + "id": "b", + "text": "A small flower stop with a twist" + }, + { + "id": "c", + "text": "A shared appetizer after dinner" + }, + { + "id": "d", + "text": "A later checkout of the night" + }, + { + "id": "e", + "text": "Better dessert" + } + ] + } + }, + { + "id": "date_night_169", + "category_id": "date_night", + "type": "multi_choice", + "text": "Choose the date-night extras that sound worth paying for:", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "little_luxury" + ], + "options": [ + { + "id": "a", + "text": "A later checkout of the night" + }, + { + "id": "b", + "text": "Good seats" + }, + { + "id": "c", + "text": "A shared appetizer this month" + }, + { + "id": "d", + "text": "A ride instead of parking stress for this date" + }, + { + "id": "e", + "text": "Better dessert" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A later checkout of the night" + }, + { + "id": "b", + "text": "Good seats" + }, + { + "id": "c", + "text": "A shared appetizer this month" + }, + { + "id": "d", + "text": "A ride instead of parking stress for this date" + }, + { + "id": "e", + "text": "Better dessert" + } + ] + } + }, + { + "id": "date_night_170", + "category_id": "date_night", + "type": "multi_choice", + "text": "Select the little luxuries that fit us:", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "little_luxury" + ], + "options": [ + { + "id": "a", + "text": "Better dessert for this date" + }, + { + "id": "b", + "text": "Good seats" + }, + { + "id": "c", + "text": "A ride instead of parking stress with a twist" + }, + { + "id": "d", + "text": "A prettier table" + }, + { + "id": "e", + "text": "A drink somewhere nice for this date" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "Better dessert for this date" + }, + { + "id": "b", + "text": "Good seats" + }, + { + "id": "c", + "text": "A ride instead of parking stress with a twist" + }, + { + "id": "d", + "text": "A prettier table" + }, + { + "id": "e", + "text": "A drink somewhere nice for this date" + } + ] + } + }, + { + "id": "date_night_171", + "category_id": "date_night", + "type": "multi_choice", + "text": "Pick the memory-making touches that sound natural:", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "memory" + ], + "options": [ + { + "id": "a", + "text": "A photo we both like" + }, + { + "id": "b", + "text": "A place with a view somewhere new" + }, + { + "id": "c", + "text": "Trying something new" + }, + { + "id": "d", + "text": "A funny moment we create" + }, + { + "id": "e", + "text": "A song tied to the night" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A photo we both like" + }, + { + "id": "b", + "text": "A place with a view somewhere new" + }, + { + "id": "c", + "text": "Trying something new" + }, + { + "id": "d", + "text": "A funny moment we create" + }, + { + "id": "e", + "text": "A song tied to the night" + } + ] + } + }, + { + "id": "date_night_172", + "category_id": "date_night", + "type": "multi_choice", + "text": "Which date details would we want to remember?", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "memory" + ], + "options": [ + { + "id": "a", + "text": "A funny moment we create" + }, + { + "id": "b", + "text": "A walk after dinner with a twist" + }, + { + "id": "c", + "text": "Trying something new" + }, + { + "id": "d", + "text": "A dessert worth mentioning" + }, + { + "id": "e", + "text": "A song tied to the night" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A funny moment we create" + }, + { + "id": "b", + "text": "A walk after dinner with a twist" + }, + { + "id": "c", + "text": "Trying something new" + }, + { + "id": "d", + "text": "A dessert worth mentioning" + }, + { + "id": "e", + "text": "A song tied to the night" + } + ] + } + }, + { + "id": "date_night_173", + "category_id": "date_night", + "type": "multi_choice", + "text": "What would make the date worth talking about later?", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "memory" + ], + "options": [ + { + "id": "a", + "text": "A song tied to the night" + }, + { + "id": "b", + "text": "A walk after dinner somewhere new" + }, + { + "id": "c", + "text": "A dessert worth mentioning" + }, + { + "id": "d", + "text": "A small surprise" + }, + { + "id": "e", + "text": "A photo we both like" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A song tied to the night" + }, + { + "id": "b", + "text": "A walk after dinner somewhere new" + }, + { + "id": "c", + "text": "A dessert worth mentioning" + }, + { + "id": "d", + "text": "A small surprise" + }, + { + "id": "e", + "text": "A photo we both like" + } + ] + } + }, + { + "id": "date_night_174", + "category_id": "date_night", + "type": "multi_choice", + "text": "Choose the pieces that make a date feel memorable:", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "memory" + ], + "options": [ + { + "id": "a", + "text": "A small surprise" + }, + { + "id": "b", + "text": "A place with a view before dessert" + }, + { + "id": "c", + "text": "A dessert worth mentioning" + }, + { + "id": "d", + "text": "Trying something new" + }, + { + "id": "e", + "text": "A photo we both like" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A small surprise" + }, + { + "id": "b", + "text": "A place with a view before dessert" + }, + { + "id": "c", + "text": "A dessert worth mentioning" + }, + { + "id": "d", + "text": "Trying something new" + }, + { + "id": "e", + "text": "A photo we both like" + } + ] + } + }, + { + "id": "date_night_175", + "category_id": "date_night", + "type": "multi_choice", + "text": "Select anything that would turn a simple date into a memory:", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "memory" + ], + "options": [ + { + "id": "a", + "text": "A photo we both like for this date" + }, + { + "id": "b", + "text": "A place with a view after dinner" + }, + { + "id": "c", + "text": "Trying something new for this date" + }, + { + "id": "d", + "text": "A funny moment we create" + }, + { + "id": "e", + "text": "A song tied to the night for this date" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A photo we both like for this date" + }, + { + "id": "b", + "text": "A place with a view after dinner" + }, + { + "id": "c", + "text": "Trying something new for this date" + }, + { + "id": "d", + "text": "A funny moment we create" + }, + { + "id": "e", + "text": "A song tied to the night for this date" + } + ] + } + }, + { + "id": "date_night_176", + "category_id": "date_night", + "type": "multi_choice", + "text": "Pick the spontaneous date ideas that would not annoy us:", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "spontaneous" + ], + "options": [ + { + "id": "a", + "text": "Dessert somewhere close" + }, + { + "id": "b", + "text": "A short drive" + }, + { + "id": "c", + "text": "A walk with coffee" + }, + { + "id": "d", + "text": "A movie starting soon" + }, + { + "id": "e", + "text": "A place from our saved list" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "Dessert somewhere close" + }, + { + "id": "b", + "text": "A short drive" + }, + { + "id": "c", + "text": "A walk with coffee" + }, + { + "id": "d", + "text": "A movie starting soon" + }, + { + "id": "e", + "text": "A place from our saved list" + } + ] + } + }, + { + "id": "date_night_177", + "category_id": "date_night", + "type": "multi_choice", + "text": "Which last-minute plans sound safe?", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "spontaneous" + ], + "options": [ + { + "id": "a", + "text": "A movie starting soon" + }, + { + "id": "b", + "text": "Takeout with a real setup for this date" + }, + { + "id": "c", + "text": "A walk with coffee for this date" + }, + { + "id": "d", + "text": "A late breakfast plan" + }, + { + "id": "e", + "text": "A place from our saved list" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A movie starting soon" + }, + { + "id": "b", + "text": "Takeout with a real setup for this date" + }, + { + "id": "c", + "text": "A walk with coffee for this date" + }, + { + "id": "d", + "text": "A late breakfast plan" + }, + { + "id": "e", + "text": "A place from our saved list" + } + ] + } + }, + { + "id": "date_night_178", + "category_id": "date_night", + "type": "multi_choice", + "text": "What should we choose when we did not plan ahead?", + "depth": 2, + "access": "premium", + "tags": [ + "date_night", + "multi_choice", + "spontaneous" + ], + "options": [ + { + "id": "a", + "text": "A place from our saved list" + }, + { + "id": "b", + "text": "Takeout with a real setup with a twist" + }, + { + "id": "c", + "text": "A late breakfast plan" + }, + { + "id": "d", + "text": "A quick stop somewhere pretty" + }, + { + "id": "e", + "text": "Dessert somewhere close" + } + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A place from our saved list" + }, + { + "id": "b", + "text": "Takeout with a real setup with a twist" + }, + { + "id": "c", + "text": "A late breakfast plan" + }, + { + "id": "d", + "text": "A quick stop somewhere pretty" + }, + { + "id": "e", + "text": "Dessert somewhere close" + } + ] + } }, { "id": "date_night_179", "category_id": "date_night", - "type": "single_choice", - "text": "What makes a date feel like a reset?", - "depth": 3, + "type": "multi_choice", + "text": "Select the spontaneous date moves that could work:", + "depth": 2, "access": "premium", "tags": [ - "reset", - "date" + "date_night", + "multi_choice", + "spontaneous" ], "options": [ { - "id": "slower_pace", - "text": "Slower pace" + "id": "a", + "text": "A quick stop somewhere pretty" }, { - "id": "honest_check_in", - "text": "Honest check-in" + "id": "b", + "text": "A short drive" }, { - "id": "laughing_together", - "text": "Laughing together" + "id": "c", + "text": "A late breakfast plan" }, { - "id": "new_scenery", - "text": "New scenery" + "id": "d", + "text": "A walk with coffee with a twist" }, { - "id": "affection", - "text": "Affection" + "id": "e", + "text": "Dessert somewhere close for this date" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A quick stop somewhere pretty" + }, + { + "id": "b", + "text": "A short drive" + }, + { + "id": "c", + "text": "A late breakfast plan" + }, + { + "id": "d", + "text": "A walk with coffee with a twist" + }, + { + "id": "e", + "text": "Dessert somewhere close for this date" + } + ] + } }, { "id": "date_night_180", "category_id": "date_night", - "type": "single_choice", - "text": "What should we do if neither of us wants to plan?", - "depth": 1, + "type": "multi_choice", + "text": "Choose the unplanned ideas that still feel like a date:", + "depth": 2, "access": "premium", "tags": [ - "planning", - "low_energy" + "date_night", + "multi_choice", + "spontaneous" ], "options": [ { - "id": "default_date", - "text": "Use a default date" + "id": "a", + "text": "Dessert somewhere close with a twist" }, { - "id": "spin_wheel", - "text": "Spin the wheel" + "id": "b", + "text": "A short drive for this date" }, { - "id": "order_food", - "text": "Order food" + "id": "c", + "text": "A walk with coffee somewhere new" }, { - "id": "take_a_walk", - "text": "Take a walk" + "id": "d", + "text": "A movie starting soon" }, { - "id": "pick_tomorrow", - "text": "Pick tomorrow" + "id": "e", + "text": "A place from our saved list for this date" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "Dessert somewhere close with a twist" + }, + { + "id": "b", + "text": "A short drive for this date" + }, + { + "id": "c", + "text": "A walk with coffee somewhere new" + }, + { + "id": "d", + "text": "A movie starting soon" + }, + { + "id": "e", + "text": "A place from our saved list for this date" + } + ] + } }, { "id": "date_night_181", "category_id": "date_night", - "type": "single_choice", - "text": "What do you want more of on our dates?", + "type": "multi_choice", + "text": "Pick the daytime dates that sound good:", "depth": 2, "access": "premium", "tags": [ - "more_of", - "date" + "date_night", + "multi_choice", + "day_date" ], "options": [ { - "id": "laughter", - "text": "Laughter" + "id": "a", + "text": "Breakfast out" }, { - "id": "romance", - "text": "Romance" + "id": "b", + "text": "A market walk" }, { - "id": "quiet", - "text": "Quiet" + "id": "c", + "text": "Coffee and a bookstore" }, { - "id": "adventure", - "text": "Adventure" + "id": "d", + "text": "A park picnic" }, { - "id": "real_conversation", - "text": "Real conversation" + "id": "e", + "text": "A museum visit with a twist" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "Breakfast out" + }, + { + "id": "b", + "text": "A market walk" + }, + { + "id": "c", + "text": "Coffee and a bookstore" + }, + { + "id": "d", + "text": "A park picnic" + }, + { + "id": "e", + "text": "A museum visit with a twist" + } + ] + } }, { "id": "date_night_182", "category_id": "date_night", - "type": "single_choice", - "text": "What do you want less of on our dates?", + "type": "multi_choice", + "text": "Which day-date ideas should we try?", "depth": 2, "access": "premium", "tags": [ - "less_of", - "date" + "date_night", + "multi_choice", + "day_date" ], "options": [ { - "id": "rushing", - "text": "Rushing" + "id": "a", + "text": "A park picnic" }, { - "id": "phones", - "text": "Phones" + "id": "b", + "text": "A scenic drive before dessert" }, { - "id": "logistics", - "text": "Logistics" + "id": "c", + "text": "Coffee and a bookstore" }, { - "id": "pressure", - "text": "Pressure" + "id": "d", + "text": "Lunch somewhere new" }, { - "id": "same_old_plan", - "text": "Same old plan" + "id": "e", + "text": "A museum visit somewhere new" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A park picnic" + }, + { + "id": "b", + "text": "A scenic drive before dessert" + }, + { + "id": "c", + "text": "Coffee and a bookstore" + }, + { + "id": "d", + "text": "Lunch somewhere new" + }, + { + "id": "e", + "text": "A museum visit somewhere new" + } + ] + } }, { "id": "date_night_183", "category_id": "date_night", - "type": "single_choice", - "text": "What kind of date feels most like us?", + "type": "multi_choice", + "text": "What sounds better before evening gets busy?", "depth": 2, "access": "premium", "tags": [ - "identity", - "couple" + "date_night", + "multi_choice", + "day_date" ], "options": [ { - "id": "silly", - "text": "Silly" + "id": "a", + "text": "A museum visit before dessert" }, { - "id": "sweet", - "text": "Sweet" + "id": "b", + "text": "A scenic drive after dinner" }, { - "id": "cozy", - "text": "Cozy" + "id": "c", + "text": "Lunch somewhere new" }, { - "id": "adventurous", - "text": "Adventurous" + "id": "d", + "text": "A matinee movie" }, { - "id": "simple", - "text": "Simple" + "id": "e", + "text": "Breakfast out" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A museum visit before dessert" + }, + { + "id": "b", + "text": "A scenic drive after dinner" + }, + { + "id": "c", + "text": "Lunch somewhere new" + }, + { + "id": "d", + "text": "A matinee movie" + }, + { + "id": "e", + "text": "Breakfast out" + } + ] + } }, { "id": "date_night_184", "category_id": "date_night", - "type": "single_choice", - "text": "What would make a planned date feel less stiff?", + "type": "multi_choice", + "text": "Choose the date ideas that fit daylight:", "depth": 2, "access": "premium", "tags": [ - "planning", - "ease" + "date_night", + "multi_choice", + "day_date" ], "options": [ { - "id": "flexible_timing", - "text": "Flexible timing" + "id": "a", + "text": "A matinee movie" }, { - "id": "casual_clothes", - "text": "Casual clothes" + "id": "b", + "text": "A market walk" }, { - "id": "playful_stop", - "text": "Playful stop" + "id": "c", + "text": "Lunch somewhere new" }, { - "id": "no_perfect_plan", - "text": "No perfect plan" + "id": "d", + "text": "Coffee and a bookstore" }, { - "id": "choosing_together", - "text": "Choosing together" + "id": "e", + "text": "Breakfast out" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A matinee movie" + }, + { + "id": "b", + "text": "A market walk" + }, + { + "id": "c", + "text": "Lunch somewhere new" + }, + { + "id": "d", + "text": "Coffee and a bookstore" + }, + { + "id": "e", + "text": "Breakfast out" + } + ] + } }, { "id": "date_night_185", "category_id": "date_night", - "type": "single_choice", - "text": "What is the best way to end a date?", + "type": "multi_choice", + "text": "Select the daytime plans that feel like us:", "depth": 2, "access": "premium", "tags": [ - "ending", - "date" + "date_night", + "multi_choice", + "day_date" ], "options": [ { - "id": "walk_inside_together", - "text": "Walk inside together" + "id": "a", + "text": "Breakfast out for this date" }, { - "id": "sweet_message", - "text": "Sweet message" + "id": "b", + "text": "A market walk" }, { - "id": "talk_for_a_minute", - "text": "Talk for a minute" + "id": "c", + "text": "Coffee and a bookstore for this date" }, { - "id": "cuddle", - "text": "Cuddle" + "id": "d", + "text": "A park picnic" }, { - "id": "plan_next_one", - "text": "Plan the next one" + "id": "e", + "text": "A museum visit after dinner" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "Breakfast out for this date" + }, + { + "id": "b", + "text": "A market walk" + }, + { + "id": "c", + "text": "Coffee and a bookstore for this date" + }, + { + "id": "d", + "text": "A park picnic" + }, + { + "id": "e", + "text": "A museum visit after dinner" + } + ] + } }, { "id": "date_night_186", "category_id": "date_night", - "type": "single_choice", - "text": "What would help us keep date night from becoming routine?", + "type": "multi_choice", + "text": "Pick the slow-date details we would both enjoy:", "depth": 2, "access": "premium", "tags": [ - "routine", - "novelty" + "date_night", + "multi_choice", + "slow_date" ], "options": [ { - "id": "new_places", - "text": "New places" + "id": "a", + "text": "A long dinner" }, { - "id": "new_questions", - "text": "New questions" + "id": "b", + "text": "A walk with no destination" }, { - "id": "themes", - "text": "Themes" + "id": "c", + "text": "A quiet booth" }, { - "id": "taking_turns", - "text": "Taking turns" + "id": "d", + "text": "A late dessert stop" }, { - "id": "small_surprises", - "text": "Small surprises" + "id": "e", + "text": "A slow breakfast" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A long dinner" + }, + { + "id": "b", + "text": "A walk with no destination" + }, + { + "id": "c", + "text": "A quiet booth" + }, + { + "id": "d", + "text": "A late dessert stop" + }, + { + "id": "e", + "text": "A slow breakfast" + } + ] + } }, { "id": "date_night_187", "category_id": "date_night", - "type": "single_choice", - "text": "What kind of date makes you feel safest to open up?", - "depth": 3, + "type": "multi_choice", + "text": "Which unrushed date ideas sound good?", + "depth": 2, "access": "premium", "tags": [ - "openness", - "safety" + "date_night", + "multi_choice", + "slow_date" ], "options": [ { - "id": "quiet_walk", - "text": "Quiet walk" + "id": "a", + "text": "A late dessert stop" }, { - "id": "slow_dinner", - "text": "Slow dinner" + "id": "b", + "text": "A scenic drive this month" }, { - "id": "home_date", - "text": "Home date" + "id": "c", + "text": "A quiet booth" }, { - "id": "long_drive", - "text": "Long drive" + "id": "d", + "text": "A movie without multitasking" }, { - "id": "after_laughing", - "text": "After laughing" + "id": "e", + "text": "A slow breakfast" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A late dessert stop" + }, + { + "id": "b", + "text": "A scenic drive this month" + }, + { + "id": "c", + "text": "A quiet booth" + }, + { + "id": "d", + "text": "A movie without multitasking" + }, + { + "id": "e", + "text": "A slow breakfast" + } + ] + } }, { "id": "date_night_188", "category_id": "date_night", - "type": "single_choice", - "text": "What should be our no-pressure date rule?", + "type": "multi_choice", + "text": "What makes a date feel calm without being boring?", "depth": 2, "access": "premium", "tags": [ - "pressure", - "rule" + "date_night", + "multi_choice", + "slow_date" ], "options": [ { - "id": "simple_is_enough", - "text": "Simple is enough" + "id": "a", + "text": "A slow breakfast" }, { - "id": "rain_checks_are_okay", - "text": "Rain checks are okay" + "id": "b", + "text": "A scenic drive for this date" }, { - "id": "phones_can_wait", - "text": "Phones can wait" + "id": "c", + "text": "A movie without multitasking" }, { - "id": "no_forced_talks", - "text": "No forced talks" + "id": "d", + "text": "A patio with time to sit" }, { - "id": "comfort_first", - "text": "Comfort first" + "id": "e", + "text": "A long dinner" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A slow breakfast" + }, + { + "id": "b", + "text": "A scenic drive for this date" + }, + { + "id": "c", + "text": "A movie without multitasking" + }, + { + "id": "d", + "text": "A patio with time to sit" + }, + { + "id": "e", + "text": "A long dinner" + } + ] + } }, { "id": "date_night_189", "category_id": "date_night", - "type": "single_choice", - "text": "What date would help us celebrate this season of life?", - "depth": 3, + "type": "multi_choice", + "text": "Choose the plans that give us room to breathe:", + "depth": 2, "access": "premium", "tags": [ - "celebration", - "life_stage" + "date_night", + "multi_choice", + "slow_date" ], "options": [ { - "id": "quiet_dinner", - "text": "Quiet dinner" + "id": "a", + "text": "A patio with time to sit" }, { - "id": "little_adventure", - "text": "Little adventure" + "id": "b", + "text": "A walk with no destination" }, { - "id": "weekend_morning", - "text": "Weekend morning" + "id": "c", + "text": "A movie without multitasking" }, { - "id": "dress_up_night", - "text": "Dress-up night" + "id": "d", + "text": "A quiet booth" }, { - "id": "memory_making_day", - "text": "Memory-making day" + "id": "e", + "text": "A long dinner" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A patio with time to sit" + }, + { + "id": "b", + "text": "A walk with no destination" + }, + { + "id": "c", + "text": "A movie without multitasking" + }, + { + "id": "d", + "text": "A quiet booth" + }, + { + "id": "e", + "text": "A long dinner" + } + ] + } }, { "id": "date_night_190", "category_id": "date_night", - "type": "single_choice", - "text": "What would make you say, 'that was a really good date'?", - "depth": 3, + "type": "multi_choice", + "text": "Select the date-night moves that keep the pace easy:", + "depth": 2, "access": "premium", "tags": [ - "after_date", - "satisfaction" + "date_night", + "multi_choice", + "slow_date" ], "options": [ { - "id": "felt_wanted", - "text": "I felt wanted" + "id": "a", + "text": "A long dinner for this date" }, { - "id": "we_laughed", - "text": "We laughed" + "id": "b", + "text": "A walk with no destination" }, { - "id": "we_relaxed", - "text": "We relaxed" + "id": "c", + "text": "A quiet booth for this date" }, { - "id": "we_talked_well", - "text": "We talked well" + "id": "d", + "text": "A late dessert stop" }, { - "id": "we_tried_something", - "text": "We tried something" + "id": "e", + "text": "A slow breakfast for this date" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "A long dinner for this date" + }, + { + "id": "b", + "text": "A walk with no destination" + }, + { + "id": "c", + "text": "A quiet booth for this date" + }, + { + "id": "d", + "text": "A late dessert stop" + }, + { + "id": "e", + "text": "A slow breakfast for this date" + } + ] + } }, { "id": "date_night_191", "category_id": "date_night", - "type": "multi_choice", - "text": "What helps you feel relaxed on a date with me?", - "depth": 1, - "access": "free", + "type": "scale", + "text": "For our next date, planned or spontaneous?", + "depth": 2, + "access": "premium", "tags": [ - "relaxation", - "date" - ], - "options": [ - { - "id": "no_rushing", - "text": "Not feeling rushed" - }, - { - "id": "phones_away", - "text": "Putting phones away" - }, - { - "id": "comfortable_plan", - "text": "A comfortable plan" - }, - { - "id": "easy_conversation", - "text": "Easy conversation" - }, - { - "id": "good_food", - "text": "Good food" - }, - { - "id": "affection", - "text": "Affection" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Completely spontaneous", + "maxLabel": "Planned down to the reservation" } }, { "id": "date_night_192", "category_id": "date_night", - "type": "multi_choice", - "text": "What should our next easy date include?", - "depth": 1, - "access": "free", + "type": "scale", + "text": "Date-night clothes: casual or full effort?", + "depth": 2, + "access": "premium", "tags": [ - "easy_date", - "planning" - ], - "options": [ - { - "id": "simple_food", - "text": "Simple food" - }, - { - "id": "a_walk", - "text": "A walk" - }, - { - "id": "music", - "text": "Music" - }, - { - "id": "one_good_question", - "text": "One good question" - }, - { - "id": "dessert", - "text": "Dessert" - }, - { - "id": "time_to_linger", - "text": "Time to linger" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Very casual", + "maxLabel": "Full effort" } }, { "id": "date_night_193", "category_id": "date_night", - "type": "multi_choice", - "text": "What makes a date feel special to you?", + "type": "scale", + "text": "Food choice: familiar favorite or new adventure?", "depth": 2, - "access": "free", + "access": "premium", "tags": [ - "special", - "preference" - ], - "options": [ - { - "id": "thoughtful_planning", - "text": "Thoughtful planning" - }, - { - "id": "full_attention", - "text": "Full attention" - }, - { - "id": "dressing_up", - "text": "Dressing up" - }, - { - "id": "sweet_words", - "text": "Sweet words" - }, - { - "id": "trying_something_new", - "text": "Trying something new" - }, - { - "id": "unhurried_time", - "text": "Unhurried time" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Stick with favorites", + "maxLabel": "Try something new" } }, { "id": "date_night_194", "category_id": "date_night", - "type": "multi_choice", - "text": "What gets in the way of date night most often?", + "type": "scale", + "text": "Conversation level for the next date?", "depth": 2, - "access": "free", + "access": "premium", "tags": [ - "barriers", - "date_night" - ], - "options": [ - { - "id": "time", - "text": "Time" - }, - { - "id": "money", - "text": "Money" - }, - { - "id": "being_tired", - "text": "Being tired" - }, - { - "id": "planning_load", - "text": "Planning load" - }, - { - "id": "phones", - "text": "Phones" - }, - { - "id": "last_minute_stress", - "text": "Last-minute stress" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Mostly easy company", + "maxLabel": "Lots of conversation" } }, { "id": "date_night_195", "category_id": "date_night", - "type": "multi_choice", - "text": "What would make an at-home date feel less ordinary?", - "depth": 1, + "type": "scale", + "text": "How far should we travel for date night?", + "depth": 2, "access": "premium", "tags": [ - "home_date", - "special" - ], - "options": [ - { - "id": "lighting", - "text": "Lighting" - }, - { - "id": "music", - "text": "Music" - }, - { - "id": "favorite_food", - "text": "Favorite food" - }, - { - "id": "fresh_pajamas", - "text": "Fresh pajamas" - }, - { - "id": "phones_away", - "text": "Phones away" - }, - { - "id": "a_game_or_questions", - "text": "A game or questions" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Stay close", + "maxLabel": "Make a little trip of it" } }, { "id": "date_night_196", "category_id": "date_night", - "type": "multi_choice", - "text": "What could help us make dates happen more often?", + "type": "scale", + "text": "Romance level for the next date?", "depth": 2, "access": "premium", "tags": [ - "consistency", - "planning" - ], - "options": [ - { - "id": "default_plan", - "text": "A default plan" - }, - { - "id": "shared_list", - "text": "A shared idea list" - }, - { - "id": "smaller_dates", - "text": "Smaller dates" - }, - { - "id": "taking_turns", - "text": "Taking turns" - }, - { - "id": "setting_a_budget", - "text": "Setting a budget" - }, - { - "id": "calendar_reminder", - "text": "Calendar reminder" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Light and easy", + "maxLabel": "Very romantic" } }, { "id": "date_night_197", "category_id": "date_night", - "type": "multi_choice", - "text": "What kinds of dates help you feel closer to me?", - "depth": 3, + "type": "scale", + "text": "Spending level for date night?", + "depth": 2, "access": "premium", "tags": [ - "closeness", - "date" - ], - "options": [ - { - "id": "slow_conversation", - "text": "Slow conversation" - }, - { - "id": "laughing_together", - "text": "Laughing together" - }, - { - "id": "new_experience", - "text": "New experience" - }, - { - "id": "quiet_affection", - "text": "Quiet affection" - }, - { - "id": "making_something", - "text": "Making something" - }, - { - "id": "revisiting_memories", - "text": "Revisiting memories" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Keep it simple", + "maxLabel": "Make it a treat" } }, { "id": "date_night_198", "category_id": "date_night", - "type": "multi_choice", - "text": "What makes a date feel too stressful?", + "type": "scale", + "text": "Surprise level for the next date?", "depth": 2, "access": "premium", "tags": [ - "stress", - "date" - ], - "options": [ - { - "id": "too_many_steps", - "text": "Too many steps" - }, - { - "id": "crowds", - "text": "Crowds" - }, - { - "id": "spending_too_much", - "text": "Spending too much" - }, - { - "id": "unclear_plan", - "text": "Unclear plan" - }, - { - "id": "being_rushed", - "text": "Being rushed" - }, - { - "id": "heavy_topics", - "text": "Heavy topics" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "No surprises", + "maxLabel": "Surprise me" } }, { "id": "date_night_199", "category_id": "date_night", - "type": "multi_choice", - "text": "What would make you feel wanted before the date even starts?", - "depth": 3, + "type": "scale", + "text": "Date-night energy: relaxed or active?", + "depth": 2, "access": "premium", "tags": [ - "feeling_wanted", - "before_date" - ], - "options": [ - { - "id": "personal_invite", - "text": "A personal invite" - }, - { - "id": "sweet_message", - "text": "A sweet message" - }, - { - "id": "clear_plan", - "text": "A clear plan" - }, - { - "id": "remembered_detail", - "text": "A remembered detail" - }, - { - "id": "compliment", - "text": "A compliment" - }, - { - "id": "excitement_from_you", - "text": "Excitement from you" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Mostly sitting", + "maxLabel": "Moving around" } }, { "id": "date_night_200", "category_id": "date_night", - "type": "multi_choice", - "text": "What helps a date stay playful?", - "depth": 1, + "type": "scale", + "text": "Newness level for our next plan?", + "depth": 2, "access": "premium", "tags": [ - "playfulness", - "date" - ], - "options": [ - { - "id": "games", - "text": "Games" - }, - { - "id": "inside_jokes", - "text": "Inside jokes" - }, - { - "id": "trying_new_food", - "text": "Trying new food" - }, - { - "id": "friendly_competition", - "text": "Friendly competition" - }, - { - "id": "silly_photos", - "text": "Silly photos" - }, - { - "id": "not_overplanning", - "text": "Not overplanning" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Repeat what works", + "maxLabel": "New plan" } }, { "id": "date_night_201", "category_id": "date_night", - "type": "multi_choice", - "text": "What date-night topics usually feel good?", + "type": "scale", + "text": "End time: early night or late one?", "depth": 2, "access": "premium", "tags": [ - "conversation", - "topics" - ], - "options": [ - { - "id": "memories", - "text": "Good memories" - }, - { - "id": "future_ideas", - "text": "Future ideas" - }, - { - "id": "funny_stories", - "text": "Funny stories" - }, - { - "id": "dreams", - "text": "Dreams" - }, - { - "id": "what_we_appreciate", - "text": "What we appreciate" - }, - { - "id": "something_new", - "text": "Something new" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Early night", + "maxLabel": "Let it run late" } }, { "id": "date_night_202", "category_id": "date_night", - "type": "multi_choice", - "text": "What topics should we save for another time during a date?", + "type": "scale", + "text": "Phone level during the date?", "depth": 2, "access": "premium", "tags": [ - "conversation", - "boundaries" - ], - "options": [ - { - "id": "money_stress", - "text": "Money stress" - }, - { - "id": "work_problems", - "text": "Work problems" - }, - { - "id": "family_drama", - "text": "Family drama" - }, - { - "id": "unfinished_arguments", - "text": "Unfinished arguments" - }, - { - "id": "chores", - "text": "Chores" - }, - { - "id": "big_decisions", - "text": "Big decisions" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "A little less scrolling", + "maxLabel": "Fully away" } }, { "id": "date_night_203", "category_id": "date_night", - "type": "multi_choice", - "text": "What would make a low-cost date feel meaningful?", + "type": "scale", + "text": "Dinner style: familiar or fancy?", "depth": 2, "access": "premium", "tags": [ - "low_cost", - "meaning" - ], - "options": [ - { - "id": "being_present", - "text": "Being present" - }, - { - "id": "thoughtful_plan", - "text": "Thoughtful plan" - }, - { - "id": "favorite_snack", - "text": "Favorite snack" - }, - { - "id": "pretty_place", - "text": "Pretty place" - }, - { - "id": "good_question", - "text": "Good question" - }, - { - "id": "sweet_ending", - "text": "Sweet ending" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Comfortable favorite", + "maxLabel": "Dress-up dinner" } }, { "id": "date_night_204", "category_id": "date_night", - "type": "multi_choice", - "text": "What helps us recover when a date does not go as planned?", - "depth": 3, + "type": "scale", + "text": "Spontaneity level for this week?", + "depth": 2, "access": "premium", "tags": [ - "flexibility", - "repair" - ], - "options": [ - { - "id": "laughing_it_off", - "text": "Laughing it off" - }, - { - "id": "choosing_a_backup", - "text": "Choosing a backup" - }, - { - "id": "not_blaming", - "text": "Not blaming" - }, - { - "id": "keeping_it_simple", - "text": "Keeping it simple" - }, - { - "id": "trying_again", - "text": "Trying again" - }, - { - "id": "ending_kindly", - "text": "Ending kindly" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Clear plan first", + "maxLabel": "Make it up as we go" } }, { "id": "date_night_205", "category_id": "date_night", - "type": "multi_choice", - "text": "What would make our next date feel more romantic?", + "type": "scale", + "text": "Music level for the date?", "depth": 2, "access": "premium", "tags": [ - "romance", - "next_date" - ], - "options": [ - { - "id": "slow_pace", - "text": "Slow pace" - }, - { - "id": "meaningful_words", - "text": "Meaningful words" - }, - { - "id": "flirting", - "text": "Flirting" - }, - { - "id": "affection", - "text": "Affection" - }, - { - "id": "dressing_up", - "text": "Dressing up" - }, - { - "id": "quiet_time", - "text": "Quiet time" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Background only", + "maxLabel": "Main part of the night" } }, { "id": "date_night_206", "category_id": "date_night", - "type": "multi_choice", - "text": "What would make our next date feel more fun?", - "depth": 1, + "type": "scale", + "text": "Cozy level for a stay-in date?", + "depth": 2, "access": "premium", "tags": [ - "fun", - "next_date" - ], - "options": [ - { - "id": "new_activity", - "text": "New activity" - }, - { - "id": "game", - "text": "Game" - }, - { - "id": "music", - "text": "Music" - }, - { - "id": "dessert_stop", - "text": "Dessert stop" - }, - { - "id": "silly_theme", - "text": "Silly theme" - }, - { - "id": "spontaneous_stop", - "text": "Spontaneous stop" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Simple and relaxed", + "maxLabel": "Full cozy setup" } }, { "id": "date_night_207", "category_id": "date_night", - "type": "multi_choice", - "text": "What would make our next date feel more peaceful?", + "type": "scale", + "text": "Flirt level for date night?", "depth": 2, "access": "premium", "tags": [ - "peace", - "next_date" - ], - "options": [ - { - "id": "quiet_place", - "text": "Quiet place" - }, - { - "id": "no_rushing", - "text": "No rushing" - }, - { - "id": "simple_food", - "text": "Simple food" - }, - { - "id": "phones_away", - "text": "Phones away" - }, - { - "id": "comfortable_clothes", - "text": "Comfortable clothes" - }, - { - "id": "no_big_talks", - "text": "No big talks" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Subtle and sweet", + "maxLabel": "Very obvious" } }, { "id": "date_night_208", "category_id": "date_night", - "type": "multi_choice", - "text": "What would make date planning feel like teamwork?", + "type": "scale", + "text": "Dessert importance for the next date?", "depth": 2, "access": "premium", "tags": [ - "teamwork", - "planning" - ], - "options": [ - { - "id": "both_suggesting_ideas", - "text": "Both suggesting ideas" - }, - { - "id": "clear_budget", - "text": "Clear budget" - }, - { - "id": "taking_turns", - "text": "Taking turns" - }, - { - "id": "sharing_logistics", - "text": "Sharing logistics" - }, - { - "id": "being_flexible", - "text": "Being flexible" - }, - { - "id": "appreciating_effort", - "text": "Appreciating effort" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Optional", + "maxLabel": "Required" } }, { "id": "date_night_209", "category_id": "date_night", - "type": "multi_choice", - "text": "What should we add to our date-night bucket list?", - "depth": 1, + "type": "scale", + "text": "Old favorite or new memory?", + "depth": 2, "access": "premium", "tags": [ - "bucket_list", - "date_ideas" - ], - "options": [ - { - "id": "new_restaurant", - "text": "New restaurant" - }, - { - "id": "live_music", - "text": "Live music" - }, - { - "id": "class_or_workshop", - "text": "Class or workshop" - }, - { - "id": "day_trip", - "text": "Day trip" - }, - { - "id": "sunset_walk", - "text": "Sunset walk" - }, - { - "id": "stay_home_theme_night", - "text": "Stay-home theme night" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Try a new place", + "maxLabel": "Bring back a favorite" } }, { "id": "date_night_210", "category_id": "date_night", - "type": "multi_choice", - "text": "What would help date night feel good during a busy season?", - "depth": 3, + "type": "scale", + "text": "Celebration level for the next date?", + "depth": 2, "access": "premium", "tags": [ - "busy_life", - "date_night" - ], - "options": [ - { - "id": "shorter_dates", - "text": "Shorter dates" - }, - { - "id": "simple_food", - "text": "Simple food" - }, - { - "id": "planning_ahead", - "text": "Planning ahead" - }, - { - "id": "lower_expectations", - "text": "Lower expectations" - }, - { - "id": "more_grace", - "text": "More grace" - }, - { - "id": "protecting_the_time", - "text": "Protecting the time" - } + "date_night", + "scale" ], "answer_config": { - "min_selections": 1, - "max_selections": 3 + "minScale": 1, + "maxScale": 5, + "minLabel": "Normal night", + "maxLabel": "Make it special" } }, { "id": "date_night_211", "category_id": "date_night", "type": "scale", - "text": "How much do you want a date night this week?", - "depth": 1, - "access": "free", + "text": "Outdoor-date priority?", + "depth": 2, + "access": "premium", "tags": [ - "weekly", - "desire" + "date_night", + "scale" ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not much", - "max_label": "Very much", - "scale_step": 1 + "minScale": 1, + "maxScale": 5, + "minLabel": "Does not matter", + "maxLabel": "Outdoor date if possible" } }, { "id": "date_night_212", "category_id": "date_night", "type": "scale", - "text": "How easy does date planning feel for us right now?", + "text": "Memory-making level for the night?", "depth": 2, - "access": "free", + "access": "premium", "tags": [ - "planning", - "ease" + "date_night", + "scale" ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Hard", - "max_label": "Easy", - "scale_step": 1 + "minScale": 1, + "maxScale": 5, + "minLabel": "Just enjoy it", + "maxLabel": "Photo-worthy night" } }, { "id": "date_night_213", "category_id": "date_night", "type": "scale", - "text": "How connected do you usually feel after our dates?", - "depth": 3, - "access": "free", + "text": "Budget priority for date night?", + "depth": 2, + "access": "premium", "tags": [ - "connection", - "after_date" + "date_night", + "scale" ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not connected", - "max_label": "Very connected", - "scale_step": 1 + "minScale": 1, + "maxScale": 5, + "minLabel": "Spend a little", + "maxLabel": "Keep it low-cost" } }, { "id": "date_night_214", "category_id": "date_night", "type": "scale", - "text": "How present do you feel I am during dates?", - "depth": 3, + "text": "Planning style: together or surprise?", + "depth": 2, "access": "premium", "tags": [ - "presence", - "attention" + "date_night", + "scale" ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Distracted", - "max_label": "Very present", - "scale_step": 1 + "minScale": 1, + "maxScale": 5, + "minLabel": "Pick together", + "maxLabel": "One person surprises the other" } }, { "id": "date_night_215", "category_id": "date_night", "type": "scale", - "text": "How present do you feel during dates?", + "text": "Date length: short and sweet or unhurried?", "depth": 2, "access": "premium", "tags": [ - "presence", - "self" + "date_night", + "scale" ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Distracted", - "max_label": "Very present", - "scale_step": 1 + "minScale": 1, + "maxScale": 5, + "minLabel": "Short and sweet", + "maxLabel": "Take our time" } }, { "id": "date_night_216", "category_id": "date_night", "type": "scale", - "text": "How much does comfort matter to you on dates?", + "text": "Early-date energy level?", "depth": 2, "access": "premium", "tags": [ - "comfort", - "importance" + "date_night", + "scale" ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not much", - "max_label": "Very much", - "scale_step": 1 + "minScale": 1, + "maxScale": 5, + "minLabel": "Not much", + "maxLabel": "Bring that energy back" } }, { "id": "date_night_217", "category_id": "date_night", "type": "scale", - "text": "How much does novelty matter to you on dates?", + "text": "Walk-after level?", "depth": 2, "access": "premium", "tags": [ - "novelty", - "importance" + "date_night", + "scale" ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not much", - "max_label": "Very much", - "scale_step": 1 + "minScale": 1, + "maxScale": 5, + "minLabel": "Skip the walk", + "maxLabel": "Definitely walk" } }, { "id": "date_night_218", "category_id": "date_night", "type": "scale", - "text": "How romantic do our dates feel lately?", - "depth": 3, + "text": "Ambiance priority for the next date?", + "depth": 2, "access": "premium", "tags": [ - "romance", - "recent" + "date_night", + "scale" ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not romantic", - "max_label": "Very romantic", - "scale_step": 1 + "minScale": 1, + "maxScale": 5, + "minLabel": "Food matters more", + "maxLabel": "Ambiance matters a lot" } }, { "id": "date_night_219", "category_id": "date_night", "type": "scale", - "text": "How playful do our dates feel lately?", + "text": "Local-event interest?", "depth": 2, "access": "premium", "tags": [ - "playfulness", - "recent" + "date_night", + "scale" ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not playful", - "max_label": "Very playful", - "scale_step": 1 + "minScale": 1, + "maxScale": 5, + "minLabel": "Maybe later", + "maxLabel": "Find one soon" } }, { "id": "date_night_220", "category_id": "date_night", "type": "scale", - "text": "How often do phones get in the way of date night?", + "text": "Unwind level for date night?", "depth": 2, "access": "premium", "tags": [ - "phones", - "distraction" + "date_night", + "scale" ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Rarely", - "max_label": "Very often", - "scale_step": 1 + "minScale": 1, + "maxScale": 5, + "minLabel": "Just enough", + "maxLabel": "Make it the whole point" } }, { "id": "date_night_221", "category_id": "date_night", "type": "scale", - "text": "How much planning pressure do you feel around dates?", - "depth": 3, + "text": "Flexibility level for the plan?", + "depth": 2, "access": "premium", "tags": [ - "planning", - "pressure" + "date_night", + "scale" ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "None", - "max_label": "A lot", - "scale_step": 1 + "minScale": 1, + "maxScale": 5, + "minLabel": "Clear schedule", + "maxLabel": "Loose plan" } }, { "id": "date_night_222", "category_id": "date_night", "type": "scale", - "text": "How balanced does date planning feel between us?", - "depth": 3, + "text": "Activity level for the date?", + "depth": 2, "access": "premium", "tags": [ - "planning", - "balance" + "date_night", + "scale" ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Unbalanced", - "max_label": "Very balanced", - "scale_step": 1 + "minScale": 1, + "maxScale": 5, + "minLabel": "Mostly talking", + "maxLabel": "Do something together" } }, { "id": "date_night_223", "category_id": "date_night", "type": "scale", - "text": "How much do budget worries affect date night?", - "depth": 3, + "text": "Outfit effort for date night?", + "depth": 2, "access": "premium", "tags": [ - "budget", - "stress" + "date_night", + "scale" ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not at all", - "max_label": "A lot", - "scale_step": 1 + "minScale": 1, + "maxScale": 5, + "minLabel": "Normal clothes", + "maxLabel": "Make it an outfit" } }, { "id": "date_night_224", "category_id": "date_night", "type": "scale", - "text": "How much do you enjoy surprise dates?", + "text": "Weeknight or weekend energy?", "depth": 2, "access": "premium", "tags": [ - "surprise", - "enjoyment" + "date_night", + "scale" ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not much", - "max_label": "Very much", - "scale_step": 1 + "minScale": 1, + "maxScale": 5, + "minLabel": "Weeknight works", + "maxLabel": "Weekend only" } }, { "id": "date_night_225", "category_id": "date_night", "type": "scale", - "text": "How much notice do you like before a planned date?", + "text": "Regular date-night habit level?", "depth": 2, "access": "premium", "tags": [ - "notice", - "planning" + "date_night", + "scale" ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Very little", - "max_label": "A lot", - "scale_step": 1 + "minScale": 1, + "maxScale": 5, + "minLabel": "Sometimes", + "maxLabel": "Put it on the calendar" } }, { "id": "date_night_226", "category_id": "date_night", - "type": "scale", - "text": "How comfortable are you asking for the date you want?", - "depth": 3, + "type": "this_or_that", + "text": "Which date sounds better this week?", + "depth": 1, "access": "premium", "tags": [ - "communication", - "comfort" + "date_night", + "this_or_that" + ], + "options": [ + { + "id": "a", + "text": "Coffee walk" + }, + { + "id": "b", + "text": "Dinner out" + } ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Uncomfortable", - "max_label": "Very comfortable", - "scale_step": 1 + "options": [ + { + "id": "a", + "text": "Coffee walk" + }, + { + "id": "b", + "text": "Dinner out" + } + ], + "optionA": "Coffee walk", + "optionB": "Dinner out" } }, { "id": "date_night_227", "category_id": "date_night", - "type": "scale", - "text": "How much do simple dates mean to you?", - "depth": 2, + "type": "this_or_that", + "text": "Which would we rather do next?", + "depth": 1, "access": "premium", "tags": [ - "simple_dates", - "meaning" + "date_night", + "this_or_that" + ], + "options": [ + { + "id": "a", + "text": "Try a new place" + }, + { + "id": "b", + "text": "Repeat a favorite" + } ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not much", - "max_label": "Very much", - "scale_step": 1 + "options": [ + { + "id": "a", + "text": "Try a new place" + }, + { + "id": "b", + "text": "Repeat a favorite" + } + ], + "optionA": "Try a new place", + "optionB": "Repeat a favorite" } }, { "id": "date_night_228", "category_id": "date_night", - "type": "scale", - "text": "How much do date nights help us reset?", - "depth": 3, + "type": "this_or_that", + "text": "Which date-night mood wins?", + "depth": 1, "access": "premium", "tags": [ - "reset", - "date_night" + "date_night", + "this_or_that" + ], + "options": [ + { + "id": "a", + "text": "Cozy night in" + }, + { + "id": "b", + "text": "Dressed-up night out" + } ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not much", - "max_label": "Very much", - "scale_step": 1 + "options": [ + { + "id": "a", + "text": "Cozy night in" + }, + { + "id": "b", + "text": "Dressed-up night out" + } + ], + "optionA": "Cozy night in", + "optionB": "Dressed-up night out" } }, { "id": "date_night_229", "category_id": "date_night", - "type": "scale", - "text": "How much should our next date focus on rest?", - "depth": 2, + "type": "this_or_that", + "text": "Which ending sounds better?", + "depth": 1, "access": "premium", "tags": [ - "rest", - "focus" + "date_night", + "this_or_that" + ], + "options": [ + { + "id": "a", + "text": "Dessert after dinner" + }, + { + "id": "b", + "text": "Walk after dinner" + } ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not much", - "max_label": "Very much", - "scale_step": 1 + "options": [ + { + "id": "a", + "text": "Dessert after dinner" + }, + { + "id": "b", + "text": "Walk after dinner" + } + ], + "optionA": "Dessert after dinner", + "optionB": "Walk after dinner" } }, { "id": "date_night_230", "category_id": "date_night", - "type": "scale", - "text": "How much should our next date focus on fun?", - "depth": 2, + "type": "this_or_that", + "text": "Which plan fits us more?", + "depth": 1, "access": "premium", "tags": [ - "fun", - "focus" + "date_night", + "this_or_that" + ], + "options": [ + { + "id": "a", + "text": "Loose plan" + }, + { + "id": "b", + "text": "Reservation made" + } ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not much", - "max_label": "Very much", - "scale_step": 1 + "options": [ + { + "id": "a", + "text": "Loose plan" + }, + { + "id": "b", + "text": "Reservation made" + } + ], + "optionA": "Loose plan", + "optionB": "Reservation made" } }, { "id": "date_night_231", "category_id": "date_night", - "type": "scale", - "text": "How much should our next date focus on romance?", - "depth": 3, + "type": "this_or_that", + "text": "Which sounds more like us?", + "depth": 1, "access": "premium", "tags": [ - "romance", - "focus" + "date_night", + "this_or_that" + ], + "options": [ + { + "id": "a", + "text": "Quiet corner booth" + }, + { + "id": "b", + "text": "Patio with people-watching" + } ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not much", - "max_label": "Very much", - "scale_step": 1 + "options": [ + { + "id": "a", + "text": "Quiet corner booth" + }, + { + "id": "b", + "text": "Patio with people-watching" + } + ], + "optionA": "Quiet corner booth", + "optionB": "Patio with people-watching" } }, { "id": "date_night_232", "category_id": "date_night", - "type": "scale", - "text": "How much should our next date focus on deeper conversation?", - "depth": 3, + "type": "this_or_that", + "text": "Which date is more tempting?", + "depth": 1, "access": "premium", "tags": [ - "conversation", - "focus" + "date_night", + "this_or_that" + ], + "options": [ + { + "id": "a", + "text": "Breakfast date" + }, + { + "id": "b", + "text": "Late movie" + } ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not much", - "max_label": "Very much", - "scale_step": 1 + "options": [ + { + "id": "a", + "text": "Breakfast date" + }, + { + "id": "b", + "text": "Late movie" + } + ], + "optionA": "Breakfast date", + "optionB": "Late movie" } }, { "id": "date_night_233", "category_id": "date_night", - "type": "scale", - "text": "How excited are you to plan something together?", - "depth": 2, + "type": "this_or_that", + "text": "Which should we save for later?", + "depth": 1, "access": "premium", "tags": [ - "excitement", - "planning" + "date_night", + "this_or_that" + ], + "options": [ + { + "id": "a", + "text": "Day trip" + }, + { + "id": "b", + "text": "Fancy dinner" + } ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not excited", - "max_label": "Very excited", - "scale_step": 1 + "options": [ + { + "id": "a", + "text": "Day trip" + }, + { + "id": "b", + "text": "Fancy dinner" + } + ], + "optionA": "Day trip", + "optionB": "Fancy dinner" } }, { "id": "date_night_234", "category_id": "date_night", - "type": "scale", - "text": "How much do you want more at-home dates?", + "type": "this_or_that", + "text": "Which date-night rule wins?", "depth": 1, "access": "premium", "tags": [ - "home_date", - "desire" + "date_night", + "this_or_that" + ], + "options": [ + { + "id": "a", + "text": "No phones at dinner" + }, + { + "id": "b", + "text": "Dessert is mandatory" + } ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not much", - "max_label": "Very much", - "scale_step": 1 + "options": [ + { + "id": "a", + "text": "No phones at dinner" + }, + { + "id": "b", + "text": "Dessert is mandatory" + } + ], + "optionA": "No phones at dinner", + "optionB": "Dessert is mandatory" } }, { "id": "date_night_235", "category_id": "date_night", - "type": "scale", - "text": "How much do you want more going-out dates?", + "type": "this_or_that", + "text": "Which surprise would land better?", "depth": 1, "access": "premium", "tags": [ - "going_out", - "desire" + "date_night", + "this_or_that" + ], + "options": [ + { + "id": "a", + "text": "New restaurant" + }, + { + "id": "b", + "text": "Favorite dessert" + } ], "answer_config": { - "min_scale": 1, - "max_scale": 5, - "min_label": "Not much", - "max_label": "Very much", - "scale_step": 1 + "options": [ + { + "id": "a", + "text": "New restaurant" + }, + { + "id": "b", + "text": "Favorite dessert" + } + ], + "optionA": "New restaurant", + "optionB": "Favorite dessert" } }, { "id": "date_night_236", "category_id": "date_night", "type": "this_or_that", - "text": "Which sounds better tonight?", - "depth": 1, - "access": "free", + "text": "Which is more date-like?", + "depth": 2, + "access": "premium", "tags": [ - "tonight", - "preference" + "date_night", + "this_or_that" ], "options": [ { - "id": "cozy_night_in", - "text": "Cozy night in" + "id": "a", + "text": "Cooking together" }, { - "id": "going_out", - "text": "Going out" + "id": "b", + "text": "Going out for one course" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "Cooking together" + }, + { + "id": "b", + "text": "Going out for one course" + } + ], + "optionA": "Cooking together", + "optionB": "Going out for one course" + } }, { "id": "date_night_237", "category_id": "date_night", "type": "this_or_that", - "text": "Which feels more romantic?", + "text": "Which should we pick when tired?", "depth": 2, - "access": "free", + "access": "premium", "tags": [ - "romance", - "comparison" + "date_night", + "this_or_that" ], "options": [ { - "id": "slow_dinner", - "text": "Slow dinner" + "id": "a", + "text": "Takeout setup" }, { - "id": "sunset_walk", - "text": "Sunset walk" + "id": "b", + "text": "Short dinner out" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "Takeout setup" + }, + { + "id": "b", + "text": "Short dinner out" + } + ], + "optionA": "Takeout setup", + "optionB": "Short dinner out" + } }, { "id": "date_night_238", "category_id": "date_night", "type": "this_or_that", - "text": "Which feels more fun?", - "depth": 1, - "access": "free", + "text": "Which sounds better in good weather?", + "depth": 2, + "access": "premium", "tags": [ - "fun", - "comparison" + "date_night", + "this_or_that" ], "options": [ { - "id": "game_night", - "text": "Game night" + "id": "a", + "text": "Picnic" }, { - "id": "movie_night", - "text": "Movie night" + "id": "b", + "text": "Patio dinner" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "Picnic" + }, + { + "id": "b", + "text": "Patio dinner" + } + ], + "optionA": "Picnic", + "optionB": "Patio dinner" + } }, { "id": "date_night_239", "category_id": "date_night", "type": "this_or_that", - "text": "Which should we do more?", + "text": "Which should be our backup plan?", "depth": 2, "access": "premium", "tags": [ - "frequency", - "date" + "date_night", + "this_or_that" ], "options": [ { - "id": "planned_dates", - "text": "Planned dates" + "id": "a", + "text": "Coffee and a walk for this date" }, { - "id": "spontaneous_dates", - "text": "Spontaneous dates" + "id": "b", + "text": "Movie at home" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "Coffee and a walk for this date" + }, + { + "id": "b", + "text": "Movie at home" + } + ], + "optionA": "Coffee and a walk for this date", + "optionB": "Movie at home" + } }, { "id": "date_night_240", "category_id": "date_night", "type": "this_or_that", - "text": "Which matters more for our next date?", + "text": "Which next date gets your vote?", "depth": 2, "access": "premium", "tags": [ - "priority", - "next_date" + "date_night", + "this_or_that" ], "options": [ { - "id": "comfort", - "text": "Comfort" + "id": "a", + "text": "Something familiar" }, { - "id": "novelty", - "text": "Novelty" + "id": "b", + "text": "Something new" } - ] + ], + "answer_config": { + "options": [ + { + "id": "a", + "text": "Something familiar" + }, + { + "id": "b", + "text": "Something new" + } + ], + "optionA": "Something familiar", + "optionB": "Something new" + } }, { "id": "date_night_241", "category_id": "date_night", - "type": "this_or_that", - "text": "Which should we prioritize this week?", + "type": "written", + "text": "Name one date spot we should finally try.", "depth": 2, "access": "premium", "tags": [ - "weekly", - "priority" + "date_night", + "written" ], - "options": [ - { - "id": "rest", - "text": "Rest" - }, - { - "id": "adventure", - "text": "Adventure" - } - ] + "answer_config": { + "min_length": 1, + "max_length": 500, + "placeholder": "Write a place or idea..." + } }, { "id": "date_night_242", "category_id": "date_night", - "type": "this_or_that", - "text": "Which sounds easier?", - "depth": 1, + "type": "written", + "text": "What is a small date tradition you would like us to start?", + "depth": 2, "access": "premium", "tags": [ - "ease", - "activity" + "date_night", + "written" ], - "options": [ - { - "id": "cook_together", - "text": "Cook together" - }, - { - "id": "order_in", - "text": "Order in" - } - ] + "answer_config": { + "min_length": 1, + "max_length": 500, + "placeholder": "Write the tradition..." + } }, { "id": "date_night_243", "category_id": "date_night", - "type": "this_or_that", - "text": "Which would help us reconnect?", - "depth": 3, + "type": "written", + "text": "What is one date from our past you would happily repeat?", + "depth": 2, "access": "premium", "tags": [ - "reconnect", - "choice" + "date_night", + "written" ], - "options": [ - { - "id": "deep_questions", - "text": "Deep questions" - }, - { - "id": "shared_activity", - "text": "Shared activity" - } - ] + "answer_config": { + "min_length": 1, + "max_length": 500, + "placeholder": "Write the memory..." + } }, { "id": "date_night_244", "category_id": "date_night", - "type": "this_or_that", - "text": "Which should be phone-free?", + "type": "written", + "text": "Plan a simple date we could do this month.", "depth": 2, "access": "premium", "tags": [ - "phones", - "boundary" + "date_night", + "written" ], - "options": [ - { - "id": "dinner", - "text": "Dinner" - }, - { - "id": "walk", - "text": "Walk" - } - ] + "answer_config": { + "min_length": 1, + "max_length": 500, + "placeholder": "Write the plan..." + } }, { "id": "date_night_245", "category_id": "date_night", - "type": "this_or_that", - "text": "Which feels more thoughtful?", + "type": "written", + "text": "What would make our next stay-in date feel intentional?", "depth": 2, "access": "premium", "tags": [ - "thoughtful", - "comparison" + "date_night", + "written" ], - "options": [ - { - "id": "planned_surprise", - "text": "Planned surprise" - }, - { - "id": "shared_plan", - "text": "Shared plan" - } - ] + "answer_config": { + "min_length": 1, + "max_length": 500, + "placeholder": "Write your answer..." + } }, { "id": "date_night_246", "category_id": "date_night", - "type": "this_or_that", - "text": "Which is easier to repeat?", - "depth": 1, + "type": "written", + "text": "What is one food or place that always feels like us?", + "depth": 2, "access": "premium", "tags": [ - "repeat", - "ease" + "date_night", + "written" ], - "options": [ - { - "id": "coffee_date", - "text": "Coffee date" - }, - { - "id": "evening_walk", - "text": "Evening walk" - } - ] + "answer_config": { + "min_length": 1, + "max_length": 500, + "placeholder": "Write your answer..." + } }, { "id": "date_night_247", "category_id": "date_night", - "type": "this_or_that", - "text": "Which feels more like us?", + "type": "written", + "text": "What is a date idea we keep mentioning but never book?", "depth": 2, "access": "premium", "tags": [ - "identity", - "couple" + "date_night", + "written" ], - "options": [ - { - "id": "silly_date", - "text": "Silly date" - }, - { - "id": "sweet_date", - "text": "Sweet date" - } - ] + "answer_config": { + "min_length": 1, + "max_length": 500, + "placeholder": "Write the idea..." + } }, { "id": "date_night_248", "category_id": "date_night", - "type": "this_or_that", - "text": "Which date should we save for?", + "type": "written", + "text": "What would be a thoughtful surprise for our next date?", "depth": 2, "access": "premium", "tags": [ - "saving", - "date" + "date_night", + "written" ], - "options": [ - { - "id": "concert", - "text": "Concert" - }, - { - "id": "weekend_trip", - "text": "Weekend trip" - } - ] + "answer_config": { + "min_length": 1, + "max_length": 500, + "placeholder": "Write the surprise..." + } }, { "id": "date_night_249", "category_id": "date_night", - "type": "this_or_that", - "text": "Which should we try first?", - "depth": 1, + "type": "written", + "text": "What is one thing I do on dates that you genuinely like?", + "depth": 3, "access": "premium", "tags": [ - "try_first", - "activity" + "date_night", + "written" ], - "options": [ - { - "id": "new_restaurant", - "text": "New restaurant" - }, - { - "id": "new_activity", - "text": "New activity" - } - ] + "answer_config": { + "min_length": 1, + "max_length": 500, + "placeholder": "Write your answer..." + } }, { "id": "date_night_250", "category_id": "date_night", - "type": "this_or_that", - "text": "Which ending sounds better?", - "depth": 2, + "type": "written", + "text": "What should our next date-night playlist be called?", + "depth": 3, "access": "premium", "tags": [ - "ending", - "date" + "date_night", + "written" ], - "options": [ - { - "id": "dessert_after", - "text": "Dessert after" - }, - { - "id": "quiet_drive_home", - "text": "Quiet drive home" - } - ] + "answer_config": { + "min_length": 1, + "max_length": 500, + "placeholder": "Write the title..." + } } ] }