Share bounded database pools across API repositories, consolidate sync and chat queries, and make mobile refreshes cache-aware and foreground-aware.
Add focused regression coverage, client freshness documentation, and repository agent role configuration.
Add a repository-owned Codex skill and helper for bounded Claude Code execution, model and effort selection, resumable follow-ups, and independent acceptance checks.
Combine the Android API 36 release, dares loop, RevenueCat documentation correction, and daily engagement features. Resolve migration ordering and preserve both dares expiry and streak reminder operations.
Use reported user timezones for daily response limits, expose couple streak state and reminders, and improve swipe and live-drawing synchronization with focused tests and documentation.
Completes the half-built dares feature: send a dare, respond, report done,
confirm, and get a push notification on every transition.
Backend (apps/api):
- New `dares` domain with couple-shared premium entitlement, a free weekly
send allowance, and server-enforced actor/state rules on every transition.
- `submitted` status so the recipient reports completion and the sender
confirms, rather than the sender guessing.
- Notifications ride the existing operations outbox via a trigger on
`sent_dares`. Push copy is generic; store compliance forbids dare text in a
preview and a test asserts no payload leaks it.
- Worker expiry sweep now covers `pending` as well as `active`/`submitted`;
an invitation nobody opened previously stayed open forever.
Fixes two latent defects:
- Deleting any dare that had been sent aborted with a check violation, because
`dare_id` is ON DELETE SET NULL while `sent_dares_dare_or_custom_check`
required it. Dare text is now snapshotted at send time, which also keeps a
couple's history stable across catalogue edits.
- The free send allowance was raceable: concurrent requests all read the same
count and every one succeeded. The count and insert are now serialized on
the sender's profile row.
Also ports `content_status` review metadata to the API catalogue, which had no
store-safety gating at all, and mirrors the review decision already enforced on
the legacy catalogue.
Mobile: dares screen (active/send/history), send sheet with duration presets,
home tile badging incoming dares, paywall on both proactive and 402 paths.
Verified: lint, typecheck, 379 unit tests, build, 71 integration tests against
local PostgreSQL.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Upgrade the mobile runtime and tracked Android project to compile and target API 36. Align Expo modules, React Native, Node, Gradle, and Android build tooling while preserving the custom widget sources.\n\nAdapt file-system, notification, animation, test, and Metro compatibility for the SDK 54 runtime.
The Platform Support section claimed Android was "not yet implemented".
Android has full native SDK support: getApiKey() selects the Android key,
com.android.vending.BILLING is declared in app.json, the paywall has no
platform gating, and the webhook passes event.store through unchanged so
PLAY_STORE events need no separate handling.
Also flag the entitlement ID mismatch between the "pro" fallback in
revenuecat.ts and the "Sauci Pro" value set in eas.json. A build profile
missing that variable yields isProUser: false with no error, which
presents as churn rather than as misconfiguration.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Promote the reproduced release lessons into harness enforcement: keep tracked native regeneration separate from artifact builds, separate Android build and upload authorization, use stable login readiness in Maestro, and retain the iOS 43 and Android 46 version increments.
Replace the Supabase application data plane with the Node/PostgreSQL API, migrate mobile, admin, web, and MCP callers, add controlled cutover tooling, and define hardened Dokploy infrastructure.
Remove client-side adult-content preferences and badges so the centrally reviewed catalogue is the single visibility boundary.\n\nUse neutral relationship-focused copy across onboarding, discovery, paywall, and login surfaces, and retain biometric controls under App Lock for both native platforms.
Classify every environment through the immutable allowlist and archive unknown concurrent additions. Remove the remote-project dependency while retaining fail-closed postconditions.
Keep exact audited-count assertions for the production project while allowing local and non-production fixture catalogues to be classified by the same immutable allowlist.
Hide archived and unreviewed catalogue content from existing clients through RLS and guarded recommendation RPCs. Reject stale writes, preserve historical rows, and seed reviewed defaults when the cutover removes a couple's full active selection.
Add reversible review states, audit history, and super-admin controls for catalogue entities without changing current client visibility.
Stage 30 high-risk production packs for archival review, cap generated content at non-explicit language, and preserve a checksummed pre-change production catalogue snapshot.
Mark redeem-code as verify_jwt=false in local configuration, matching its intentional unauthenticated email-and-code flow and production deployment settings.
Install the extension required by notification triggers and cron jobs so fresh local and preview databases expose net.http_post before fixtures are seeded.
Resolve each Edge Function URL when its cron job executes so fresh local databases can replay migrations before environment data is seeded. Missing configuration remains fail-closed instead of aborting database bootstrap.
Show who-likely choices in human terms and provide protected photo and audio previews in activity and user response views. Fetch media by response ID through an authenticated Edge Function that enforces the view_responses permission.
Align admin production and development images with the repository's committed npm workspace and lockfile. This ensures shared and Expo-linked dependencies are installed before the admin build runs.
Render database-backed text, audio, photo, and choice responses across admin activity and user detail views. Add support for the both_answered match state while retaining legacy swipe behavior.
Add concise routed context, task-aware agent roles, focused skills, and structured learning promotion.\n\nUnify local development and workspace tooling, add layered test and E2E verification, harden MCP authentication, and gate deployment behind verification and explicit production promotion.
- Add Fastlane setup for uploading AAB to Google Play
- Chain upload into release:android npm script
- Fix onboarding re-renders from authStore subscriptions
- Reduce unnecessary authStore state updates in fetchUser
- Bump Android versionCode to 45
Non-prod cron jobs were hardcoding production URLs, causing double
notifications. Adds get_supabase_edge_function_url() helper that
resolves from app_config.supabase_url per environment. Also adds
text_answer question type to pack generation docs.
Add automatic push notifications for behind partners (escalating: 24h then
every 3 days) and daily unpaired user reminders. Includes edge functions,
migrations, notification preference toggles, and UI improvements to pairing
and swipe screens.
The couple_packs table has no admin RLS policy, so the enabled packs
query returns empty for admin users. Query all partner-answered
questions instead — more useful for admin visibility anyway.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Shows questions the partner has answered that this user hasn't yet,
with intensity levels and partner's answer. Adds outstanding count
badge and gap-blocked indicator to the profile header.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Prevents agents from using apply_migration or DDL via execute_sql,
which breaks CI by creating remote migration entries without local files.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All 57 pre-existing migrations have been registered in prod's
schema_migrations table so db push --include-all will skip them
and only apply new migrations.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Production only had one migration tracked in schema_migrations.
With --include-all, db push tried to re-run all 57 earlier migrations.
Without it, only migrations newer than the latest tracked version are applied.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migration 20260127202703 was applied to prod via MCP but had no local
file, causing supabase db push to fail with a version mismatch.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds Sunday weekly recap push notifications summarizing couple match
activity. Includes edge function, migration, notification preference
toggle, and mobile notification handling.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Re-add is_explicit toggle on pack and dare pack forms labeled as
"NSFW". Show NSFW badge on pack cards and user enabled packs.
Remove all intensity/comfort level references from admin UI including
form fields, analytics charts, review dialog columns, AI generation
prompts/scoring, cherry-pick balancing, and settings toggles. The
database columns remain unchanged.
Use Reanimated's built-in Animated.FlatList instead of manually wrapping
with createAnimatedComponent to fix Android crash where animated scroll
handler binds before the native node is registered.
Also includes v1.0.3 version bump and expo-sharing pin.
Extract the slider track, levels, card, and modal into\nfocused subcomponents with shared styles/constants.\nPreserve the existing IntensitySlider API.
Move swipe screen logic into hooks/services and extract
state-specific UI components to keep files small while
preserving existing behavior.
Reference: US-002
The migration needs to run before add_question_type_to_recommended_questions
which depends on the question_type enum. Both had timestamp 20260125110000,
causing alphabetical sort to run them in wrong order.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use IF NOT EXISTS for CREATE TYPE
- Use ADD COLUMN IF NOT EXISTS for ALTER TABLE
- Use DROP POLICY IF EXISTS before CREATE POLICY
This allows the migration to run safely even if schema already exists.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allows migrations with timestamps before existing remote migrations
to be applied. Needed when migration files are renamed or when
environments have diverged.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The add_question_types migration had an earlier timestamp than
add_color_to_categories which was already applied to production.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- New discovery components (ContentTile, ContentRow, CircularProgress)
- Refactor home screen with compact header and content tiles
- Add hide_nsfw profile setting for content filtering
- Add color column to categories table
- Track pack progress (answered/total questions)
- Update related stores and tests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use matrix strategy to deploy sequentially: non-prod first, then prod.
This ensures both environments stay in sync and provides a safety gate.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The latest supabase-js@2.92.0 has a Deno compatibility bug with
createRequire that causes all edge functions to fail with:
"The argument 'filename' must be a file URL object..."
Pin all edge functions to @2.45.0 with ?target=deno parameter
to ensure Deno-compatible builds from esm.sh.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use grep to only match lines starting with lowercase (function names),
and add validation to skip empty or invalid names.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CLI expects supabase/functions/ relative to workdir, so --workdir apps
makes it find apps/supabase/functions/.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
supabase db push doesn't support --project-ref, it relies on link.
Run link from apps/supabase so the config is in the right place.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Allow manual triggering via workflow_dispatch
- Trigger on changes to the workflow file itself
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The supabase link command was running from repo root while db push
ran from apps/supabase, causing it to not find the linked project.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Separate string and numeric settings into different locals to prevent
merge() from coercing integers to strings. The Supabase API requires
rate_limit_email_sent to be an integer.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove root-level main.tf, variables.tf, outputs.tf, versions.tf
(duplicated the module-based approach)
- Remove duplicate terraform/templates/ directory
- Remove stale terraform.tfvars.example and .terraform.lock.hcl
- Remove outdated scripts/import-production.sh
- Fix non-prod SMTP error by using merge() to completely omit
SMTP fields instead of setting them to null
- Update README to remove workspace migration section
The environment directories approach (terraform/environments/*) is now
the only supported method.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>