managarten/maerchenzauber/context/COMMUNITY_FEATURES_PLAN.md
Till-JS e7f5f942f3 chore: initial commit - consolidate 4 projects into monorepo
Projects included:
- maerchenzauber (NestJS backend + Expo mobile + SvelteKit web + Astro landing)
- manacore (Expo mobile + SvelteKit web + Astro landing)
- manadeck (NestJS backend + Expo mobile + SvelteKit web)
- memoro (Expo mobile + SvelteKit web + Astro landing)

This commit preserves the current state before monorepo restructuring.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 23:38:24 +01:00

424 lines
No EOL
12 KiB
Markdown

# Community Features Implementation Plan
## Märchenzauber - Story & Character Sharing System
### Overview
Erweiterung der Märchenzauber App um Community-Features: Publishing, Voting, Collections und Character-Sharing.
---
## 1. Database Schema Changes
### 1.1 Stories Table Extensions
```sql
ALTER TABLE stories ADD COLUMN is_published BOOLEAN DEFAULT FALSE;
ALTER TABLE stories ADD COLUMN published_at TIMESTAMPTZ;
ALTER TABLE stories ADD COLUMN publish_consent BOOLEAN DEFAULT FALSE;
ALTER TABLE stories ADD COLUMN vote_count INTEGER DEFAULT 0;
ALTER TABLE stories ADD COLUMN featured_score DECIMAL DEFAULT 0;
```
### 1.2 Characters Table Extensions
```sql
ALTER TABLE characters ADD COLUMN is_published BOOLEAN DEFAULT FALSE;
ALTER TABLE characters ADD COLUMN published_at TIMESTAMPTZ;
ALTER TABLE characters ADD COLUMN share_code VARCHAR(12) UNIQUE;
ALTER TABLE characters ADD COLUMN total_vote_score INTEGER DEFAULT 0;
ALTER TABLE characters ADD COLUMN stories_count INTEGER DEFAULT 0;
ALTER TABLE characters ADD COLUMN sharing_preference VARCHAR(20) DEFAULT 'private'
CHECK (sharing_preference IN ('private', 'link_only', 'public', 'commons'));
ALTER TABLE characters ADD COLUMN original_creator_id TEXT;
ALTER TABLE characters ADD COLUMN original_character_id UUID;
```
### 1.3 New Tables
#### Story Collections
```sql
CREATE TABLE story_collections (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(255) NOT NULL,
description TEXT,
type VARCHAR(50) NOT NULL CHECK (type IN ('official', 'community', 'seasonal', 'contest')),
is_official BOOLEAN DEFAULT FALSE,
is_active BOOLEAN DEFAULT TRUE,
sort_order INTEGER DEFAULT 0,
icon_url TEXT,
banner_url TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
metadata JSONB DEFAULT '{}'::jsonb
);
CREATE TABLE collection_stories (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
collection_id UUID NOT NULL REFERENCES story_collections(id) ON DELETE CASCADE,
story_id UUID NOT NULL REFERENCES stories(id) ON DELETE CASCADE,
added_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
position INTEGER DEFAULT 0,
added_by TEXT,
UNIQUE(collection_id, story_id)
);
```
#### Character Collections
```sql
CREATE TABLE character_collections (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(255) NOT NULL,
description TEXT,
type VARCHAR(50) NOT NULL,
is_official BOOLEAN DEFAULT FALSE,
is_active BOOLEAN DEFAULT TRUE,
sort_order INTEGER DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE collection_characters (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
collection_id UUID NOT NULL REFERENCES character_collections(id) ON DELETE CASCADE,
character_id UUID NOT NULL REFERENCES characters(id) ON DELETE CASCADE,
added_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
position INTEGER DEFAULT 0,
UNIQUE(collection_id, character_id)
);
```
#### Voting System
```sql
CREATE TABLE story_votes (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
story_id UUID NOT NULL REFERENCES stories(id) ON DELETE CASCADE,
user_id TEXT NOT NULL,
vote_type VARCHAR(20) DEFAULT 'like' CHECK (vote_type IN ('like', 'love', 'star')),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(story_id, user_id)
);
CREATE TABLE character_votes (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
character_id UUID NOT NULL REFERENCES characters(id) ON DELETE CASCADE,
user_id TEXT NOT NULL,
vote_type VARCHAR(20) DEFAULT 'like',
source VARCHAR(20) DEFAULT 'direct' CHECK (source IN ('direct', 'story')),
story_id UUID REFERENCES stories(id) ON DELETE SET NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(character_id, user_id, COALESCE(story_id, '00000000-0000-0000-0000-000000000000'::uuid))
);
```
#### Character Usage Tracking
```sql
CREATE TABLE character_usage (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
original_character_id UUID NOT NULL REFERENCES characters(id),
user_id TEXT NOT NULL,
story_id UUID REFERENCES stories(id),
usage_type VARCHAR(20) CHECK (usage_type IN ('imported', 'public', 'shared')),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
```
---
## 2. Row Level Security (RLS) Policies
### 2.1 Published Content Visibility
```sql
-- Published stories visible to all
CREATE POLICY "published_stories_visible" ON stories
FOR SELECT USING (is_published = true OR user_id = auth.uid()::text);
-- Published characters visible to all
CREATE POLICY "published_characters_visible" ON characters
FOR SELECT USING (
is_published = true
OR sharing_preference IN ('public', 'commons')
OR user_id = auth.uid()::text
);
-- Voting accessible to authenticated users
CREATE POLICY "authenticated_users_can_vote" ON story_votes
FOR INSERT WITH CHECK (user_id = auth.uid()::text);
CREATE POLICY "users_can_see_votes" ON story_votes
FOR SELECT USING (true);
```
---
## 3. Database Functions & Triggers
### 3.1 Story Vote Cascade to Character
```sql
CREATE OR REPLACE FUNCTION cascade_story_vote_to_character()
RETURNS TRIGGER AS $$
BEGIN
-- Add vote to character
INSERT INTO character_votes (character_id, user_id, vote_type, source, story_id)
SELECT s.character_id, NEW.user_id, NEW.vote_type, 'story', NEW.story_id
FROM stories s
WHERE s.id = NEW.story_id AND s.character_id IS NOT NULL
ON CONFLICT (character_id, user_id, COALESCE(story_id, '00000000-0000-0000-0000-000000000000'::uuid))
DO NOTHING;
-- Update character vote score
UPDATE characters c
SET total_vote_score = (
SELECT COUNT(*) FROM character_votes WHERE character_id = c.id
)
WHERE c.id = (SELECT character_id FROM stories WHERE id = NEW.story_id);
-- Update story vote count
UPDATE stories
SET vote_count = vote_count + 1
WHERE id = NEW.story_id;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER story_vote_cascade_trigger
AFTER INSERT ON story_votes
FOR EACH ROW
EXECUTE FUNCTION cascade_story_vote_to_character();
```
### 3.2 Auto-generate Share Code
```sql
CREATE OR REPLACE FUNCTION generate_share_code()
RETURNS TEXT AS $$
DECLARE
chars TEXT := 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
result TEXT := '';
i INTEGER;
BEGIN
FOR i IN 1..8 LOOP
result := result || substr(chars, floor(random() * length(chars) + 1)::int, 1);
END LOOP;
RETURN result;
END;
$$ LANGUAGE plpgsql;
```
### 3.3 Update Story Count for Characters
```sql
CREATE OR REPLACE FUNCTION update_character_story_count()
RETURNS TRIGGER AS $$
BEGIN
UPDATE characters
SET stories_count = (
SELECT COUNT(*) FROM stories WHERE character_id = NEW.character_id
)
WHERE id = NEW.character_id;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER update_character_stats
AFTER INSERT ON stories
FOR EACH ROW
WHEN (NEW.character_id IS NOT NULL)
EXECUTE FUNCTION update_character_story_count();
```
---
## 4. Automatic Collections Management
### 4.1 Weekly Story Collection
```sql
-- Function to create weekly story collection
CREATE OR REPLACE FUNCTION create_weekly_story_collection()
RETURNS void AS $$
DECLARE
collection_id UUID;
week_number INTEGER;
BEGIN
week_number := EXTRACT(WEEK FROM CURRENT_DATE);
-- Create collection
INSERT INTO story_collections (name, description, type, is_official)
VALUES (
'Story der Woche KW ' || week_number || ' ' || EXTRACT(YEAR FROM CURRENT_DATE),
'Die beliebteste Geschichte dieser Woche',
'contest',
true
)
RETURNING id INTO collection_id;
-- Add top voted story
INSERT INTO collection_stories (collection_id, story_id, position)
SELECT
collection_id,
s.id,
1
FROM stories s
WHERE s.is_published = true
AND s.published_at >= CURRENT_DATE - INTERVAL '7 days'
ORDER BY s.vote_count DESC
LIMIT 1;
END;
$$ LANGUAGE plpgsql;
```
---
## 5. API Endpoints (Backend)
### 5.1 Story Publishing
- `POST /api/stories/:id/publish` - Publish a story
- `GET /api/stories/public` - Get all public stories
- `GET /api/stories/trending` - Get trending stories
### 5.2 Character Sharing
- `POST /api/characters/:id/share` - Generate share code
- `GET /api/characters/shared/:shareCode` - Get character by share code
- `POST /api/characters/:id/publish` - Publish character
- `POST /api/characters/:id/import` - Import shared character
### 5.3 Voting
- `POST /api/stories/:id/vote` - Vote for story
- `DELETE /api/stories/:id/vote` - Remove vote
- `POST /api/characters/:id/vote` - Vote for character
- `GET /api/stories/:id/votes` - Get vote count
### 5.4 Collections
- `GET /api/collections/stories` - Get story collections
- `GET /api/collections/characters` - Get character collections
- `GET /api/collections/:id/content` - Get collection content
---
## 6. Implementation Phases
### Phase 1: Foundation (Week 1-2)
1. Database schema updates
2. RLS policies
3. Basic publishing for stories
4. Simple voting system
### Phase 2: Character Sharing (Week 3-4)
1. Character publishing
2. Share code generation
3. Character import functionality
4. Usage tracking
### Phase 3: Collections (Week 5-6)
1. Collection tables and management
2. Automatic weekly collections
3. Admin tools for curation
4. Collection browsing UI
### Phase 4: Advanced Features (Week 7-8)
1. Trending algorithms
2. Recommendation system
3. Creator profiles
4. Achievement system
---
## 7. Mobile App UI Changes
### 7.1 New Screens
- **Discover**: Browse public stories and characters
- **Collections**: View curated collections
- **Voting**: Heart/star buttons on stories
- **Share Modal**: Share code display and import
### 7.2 Profile Additions
- "My Published Stories" section
- "My Published Characters" section
- Vote statistics
- Achievement badges
### 7.3 Navigation Updates
- New "Community" tab in bottom navigation
- Share buttons on story/character detail views
- Import character option in character creation
---
## 8. Admin Dashboard Requirements
### 8.1 Content Moderation
- Review published content
- Remove inappropriate content
- Feature/unfeature stories
### 8.2 Collection Management
- Create/edit collections
- Add/remove stories from collections
- Schedule seasonal collections
### 8.3 Analytics
- Vote trends
- Popular characters tracking
- User engagement metrics
---
## 9. Privacy & Safety Considerations
### 9.1 Content Guidelines
- Age-appropriate content only
- No personal information in stories
- Copyright respect for characters
### 9.2 Moderation Tools
- Report button for inappropriate content
- Automatic content scanning
- User blocking functionality
### 9.3 Data Protection
- Anonymous voting
- Optional creator attribution
- GDPR compliance for shared content
---
## 10. Success Metrics
### 10.1 Engagement KPIs
- Daily active voters
- Stories published per week
- Character reuse rate
- Collection browse rate
### 10.2 Quality Metrics
- Average votes per story
- Repeat character usage
- Time spent in collections
- User retention after publishing
---
## 11. Future Enhancements
### 11.1 Monetization Options
- Premium collections
- Character marketplace
- Story printing service
- Creator tips/donations
### 11.2 Social Features
- Follow creators
- Comments on stories
- Story remixes
- Collaborative stories
### 11.3 Gamification
- Creator levels
- Writing challenges
- Seasonal events
- Achievement system
---
## Technical Notes
- Use database indexes on frequently queried fields (is_published, vote_count)
- Implement caching for popular stories/characters
- Consider CDN for shared character images
- Add rate limiting for voting endpoints
- Implement soft delete for moderation