WIP: lokalen Stand vor dem Aufräumen sichern
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
-- nightly — Fix migration: align DB with iOS app + add missing features
|
||||
-- Run after 001_schema.sql
|
||||
|
||||
-- ── 1. Fix mood enum: replace old values with iOS app values ─────────────────
|
||||
|
||||
-- Drop dependent objects first
|
||||
DROP VIEW IF EXISTS public.feed_posts;
|
||||
|
||||
ALTER TABLE public.posts ALTER COLUMN mood TYPE text USING mood::text;
|
||||
DROP TYPE IF EXISTS public.post_mood;
|
||||
|
||||
CREATE TYPE public.post_mood AS ENUM ('still', 'unruhig', 'schwer', 'geladen', 'zart', 'dunkel');
|
||||
ALTER TABLE public.posts ALTER COLUMN mood TYPE public.post_mood USING mood::public.post_mood;
|
||||
|
||||
-- ── 2. Increase content length from 280 to 420 ───────────────────────────────
|
||||
|
||||
ALTER TABLE public.posts DROP CONSTRAINT posts_content_check;
|
||||
ALTER TABLE public.posts ADD CONSTRAINT posts_content_check
|
||||
CHECK (LENGTH(TRIM(content)) BETWEEN 1 AND 420);
|
||||
|
||||
-- ── 3. Add content warning columns to posts ─────────────────────────────────
|
||||
|
||||
ALTER TABLE public.posts ADD COLUMN IF NOT EXISTS has_content_warning BOOLEAN DEFAULT FALSE NOT NULL;
|
||||
ALTER TABLE public.posts ADD COLUMN IF NOT EXISTS content_warning_type TEXT;
|
||||
|
||||
-- ── 4. Recreate feed_posts view with content_warning fields ──────────────────
|
||||
|
||||
CREATE OR REPLACE VIEW public.feed_posts AS
|
||||
SELECT
|
||||
p.id,
|
||||
p.content,
|
||||
p.mood,
|
||||
p.is_anonymous,
|
||||
p.created_at,
|
||||
p.has_content_warning,
|
||||
p.content_warning_type,
|
||||
CASE WHEN p.is_anonymous THEN NULL ELSE p.user_id END AS author_id,
|
||||
CASE WHEN p.is_anonymous THEN NULL ELSE pr.username END AS author_username,
|
||||
CASE WHEN p.is_anonymous THEN NULL ELSE pr.display_name END AS author_display_name,
|
||||
CASE WHEN p.is_anonymous THEN NULL ELSE pr.avatar_url END AS author_avatar_url,
|
||||
COALESCE((
|
||||
SELECT COUNT(*) FROM public.resonances r WHERE r.post_id = p.id
|
||||
), 0)::int AS resonance_count
|
||||
FROM public.posts p
|
||||
JOIN public.profiles pr ON pr.id = p.user_id
|
||||
WHERE p.deleted_at IS NULL
|
||||
AND p.review_status IN ('ok', 'approved')
|
||||
AND p.created_at > NOW() - INTERVAL '14 hours';
|
||||
|
||||
-- ── 5. Add get_streak RPC ────────────────────────────────────────────────────
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.get_streak(p_user_id UUID)
|
||||
RETURNS TABLE(streak INT) LANGUAGE plpgsql STABLE AS $$
|
||||
DECLARE
|
||||
v_streak INT := 0;
|
||||
v_check_date DATE := CURRENT_DATE;
|
||||
v_has_post BOOLEAN;
|
||||
BEGIN
|
||||
LOOP
|
||||
SELECT EXISTS(
|
||||
SELECT 1 FROM public.posts
|
||||
WHERE user_id = p_user_id
|
||||
AND deleted_at IS NULL
|
||||
AND (created_at AT TIME ZONE 'Europe/Berlin')::DATE = v_check_date
|
||||
) INTO v_has_post;
|
||||
|
||||
IF v_has_post THEN
|
||||
v_streak := v_streak + 1;
|
||||
v_check_date := v_check_date - 1;
|
||||
ELSE
|
||||
EXIT;
|
||||
END IF;
|
||||
END LOOP;
|
||||
|
||||
-- Check if user posted today; if not, streak is 0
|
||||
IF v_streak = 0 THEN
|
||||
RETURN NEXT;
|
||||
ELSE
|
||||
RETURN QUERY SELECT v_streak;
|
||||
END IF;
|
||||
END;
|
||||
$$;
|
||||
|
||||
-- ── 6. Add get_resonance_count RPC ───────────────────────────────────────────
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.get_resonance_count(p_user_id UUID)
|
||||
RETURNS TABLE(count INT) LANGUAGE plpgsql STABLE AS $$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT COUNT(*)::int AS count
|
||||
FROM public.resonances r
|
||||
JOIN public.posts p ON p.id = r.post_id
|
||||
WHERE p.user_id = p_user_id
|
||||
AND p.deleted_at IS NULL;
|
||||
END;
|
||||
$$;
|
||||
|
||||
-- ── 7. Add public_profile view for other-user profile lookups ────────────────
|
||||
|
||||
CREATE OR REPLACE VIEW public.public_profile AS
|
||||
SELECT
|
||||
p.id,
|
||||
p.username,
|
||||
p.display_name,
|
||||
p.bio,
|
||||
p.avatar_url,
|
||||
p.is_pro,
|
||||
p.is_admin,
|
||||
p.created_at,
|
||||
(SELECT COUNT(*) FROM public.posts WHERE user_id = p.id AND deleted_at IS NULL)::int AS post_count,
|
||||
(SELECT COUNT(*) FROM public.resonances r JOIN public.posts p2 ON p2.id = r.post_id WHERE p2.user_id = p.id AND p2.deleted_at IS NULL)::int AS resonance_count,
|
||||
(SELECT COUNT(*) FROM public.follows WHERE following_id = p.id)::int AS follower_count,
|
||||
(SELECT COUNT(*) FROM public.follows WHERE follower_id = p.id)::int AS following_count
|
||||
FROM public.profiles p;
|
||||
|
||||
-- ── 8. Add profile view RLS (public_profile is a view, inherits from profiles) ─
|
||||
|
||||
-- Allow updates to profiles row
|
||||
-- (already handled by existing policy, no change needed)
|
||||
|
||||
-- ── 9. Enable Realtime for posts table ────────────────────────────────────────
|
||||
|
||||
ALTER PUBLICATION supabase_realtime ADD TABLE public.posts;
|
||||
|
||||
-- ── 10. Fix RLS for posts: allow reading all non-deleted approved posts ───────
|
||||
|
||||
DROP POLICY IF EXISTS posts_select ON public.posts;
|
||||
CREATE POLICY "posts_select" ON public.posts FOR SELECT
|
||||
USING (
|
||||
deleted_at IS NULL
|
||||
AND review_status IN ('ok', 'approved')
|
||||
);
|
||||
Reference in New Issue
Block a user