Campaign-to-Book Merge: Comprehensive Architecture Plan
Status: APPROVED - Ready for Implementation Author: Architecture Team Date: 2025-01-30 Last Updated: 2025-01-30
Design Decisions (Confirmed)
| Question | Decision | Rationale |
|---|---|---|
| UI terminology | βBookβ | Simple and intuitive |
| Template change after stories | Allowed with warning | Preserve content, suggest re-mapping |
| Gift recipient auto-add giver | Yes, as contributor | Natural collaboration |
| Stories shared between books | No - duplicate instead | Simpler to manage, story becomes starting point |
| Default family sharing | ON for updates (weekly) | Keep family engaged |
| Placeholder stories from template | Yes, auto-created | Give users a head start |
| Recording/AI scope | Book-specific (MVP) | Enables RAG context for better AI suggestions |
Executive Summary
This document outlines a complete plan to merge the campaigns concept into books, simplifying the data model from two related entities (Campaign β Book) into a single unified entity (Book as Project). This change aligns with the v1.1 architecture goal of Story = Chapter and creates a more intuitive user experience.
Key Changes
- Book becomes the top-level project (replaces Campaign)
- Stories belong directly to Books from creation
- Template-first approach - chosen at book creation to inform prompts
- Placeholder stories auto-created from template structure
- Storyteller info moves to Book - who the book is about
- Story duplication - copy stories between books (no sharing/linking)
- Family sharing ON by default - weekly update notifications
- Recording & AI are book-scoped - enables RAG context for better suggestions
- Simplified URL structure -
/books/[id]/stories/newinstead of/campaigns/[id]/stories/new
Table of Contents
- Current State Analysis
- Proposed Architecture
- Database Schema Changes
- Frontend Route Changes
- Component Migration
- Family Access Model
- Onboarding Flow Design
- User Journey Scenarios
- API Changes
- Data Migration Strategy
- Risk Analysis
- Implementation Phases
1. Current State Analysis
1.1 Current Data Model
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β campaigns ββββββΆβ books ββββββΆβ stories β
β β β β β β
β storyteller_* β β story_ids[] β β campaign_id β
β template_id β β template_id β β (redundant) β
β family_group_id β β family_group_id β β family_group_id β
β is_gift β β (redundant?) β β (redundant?) β
β status β β status β β β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ1.2 Current campaigns Table Fields
| Field | Purpose | Move To |
|---|---|---|
storyteller_name | Who the book is about | books.storyteller_name |
storyteller_email | Contact for storyteller | books.storyteller_email |
storyteller_phone | Contact for storyteller | books.storyteller_phone |
storyteller_notes | Notes about storyteller | books.storyteller_notes |
storyteller_user_id | If storyteller has account | books.storyteller_user_id |
template_id | Book template | Already in books |
is_gift | Gift purchase flag | books.is_gift |
gift_message | Personal message | books.gift_message |
gift_recipient_* | Gift recipient info | books.gift_recipient_* |
gift_status | Delivery status | books.gift_status |
goal_stories | Target story count | books.goal_stories |
prompt_frequency | How often to prompt | books.prompt_settings |
communication_method | Email/SMS preference | books.notification_settings |
user_role | Creatorβs relationship | books.creator_relationship |
family_group_id | Family ownership | Already in books |
is_family_shared | Sharing flag | Use family_book_permissions |
status | Campaign status | books.project_status |
setup_step | Wizard progress | books.setup_step |
setup_progress | Wizard data | books.setup_progress |
1.3 Current Route Structure
Campaigns (27 files):
/campaigns β List all campaigns
/campaigns/create β Multi-step wizard (7 steps)
/campaigns/[id] β Campaign dashboard
/campaigns/[id]/stories β Stories list
/campaigns/[id]/stories/new β Create story
/campaigns/[id]/stories/[id] β Story view
/campaigns/[id]/stories/[id]/edit β Edit story
/campaigns/[id]/ai/voice β AI voice recording
/campaigns/[id]/ai/photo β AI photo features
/campaigns/[id]/import/voice β Voice importBooks (23 files):
/books β List all books
/books/new β Book creation wizard
/books/[id] β Book detail
/books/[id]/edit β Edit book
/books/[id]/design β Design customization
/books/[id]/chapters β Chapter management
/books/[id]/chapters/[id]/edit β Edit chapter
/books/analytics β Analytics dashboard2. Proposed Architecture
2.1 New Data Model
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β books β
β (Book Project - The single top-level entity) β
β β
β Core Info: β
β title, subtitle, description β
β author_name, contributor_names[] β
β β
β Storyteller (NEW - from campaigns): β
β storyteller_name β
β storyteller_relationship (replaces user_role) β
β storyteller_user_id β
β storyteller_email, storyteller_phone β
β β
β Template & Content: β
β template_id (chosen UPFRONT) β
β story_ids[] (chapters) β
β goal_stories, completed_stories β
β β
β Project Status: β
β project_status: 'setup'|'collecting'|'editing'| β
β 'designing'|'ready'|'published' β
β setup_step, setup_progress β
β β
β Notifications (NEW): β
β prompt_frequency β
β notification_preferences (jsonb) β
β β
β Gift (NEW - from campaigns): β
β is_gift, gift_message β
β gift_recipient_name, gift_recipient_email β
β gift_status, gift_delivery_date β
β β
β Family: β
β family_group_id β
β (permissions via family_book_permissions) β
β β
β Publishing: β
β kdp_*, isbn_*, cover_*, design_settings β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
β book_id
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β stories β
β β
β book_id (NEW - replaces campaign_id) β
β title, content β
β chapter_number (derived from books.story_ids index) β
β prompt (which template prompt was used) β
β status, word_count, etc. β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ2.2 New Route Structure
# Books (primary entity - all content is book-scoped)
/books β Dashboard: All book projects
/books/new β Create book wizard (template-first)
/books/[id] β Book project dashboard
/books/[id]/stories β Stories/chapters in this book
/books/[id]/stories/new β Create story IN this book (with template prompts)
/books/[id]/stories/[sid] β View story in book context
/books/[id]/stories/[sid]/edit β Edit story (uses EnhancedEditorShell)
/books/[id]/record β Voice recording hub for this book
/books/[id]/conversations β AI conversation hub for this book
/books/[id]/design β Design customization
/books/[id]/preview β Preview book
/books/[id]/publish β Publishing flow
/books/[id]/settings β Book settings
/books/[id]/share β Sharing & permissions
# Stories (for browsing/search across all books)
/stories β Browse all user's stories across books
/stories/[id] β Redirect to /books/[book_id]/stories/[id]Key insight (MVP): All content is book-scoped for better RAG context:
- Recordings belong to a specific book β context stays consistent
- AI conversations belong to a specific book β RAG uses bookβs stories as context
- Users must choose a book before recording/AI conversations
- This enables the AI to provide more relevant, book-specific suggestions
2.3 Terminology Changes
| Old Term | New Term | Rationale |
|---|---|---|
| Campaign | Book Project | More intuitive |
| Story Project | (removed) | Redundant |
| Create Campaign | Start a Book | Simpler language |
| Campaign Status | Book Progress | Clearer meaning |
| Storyteller | Author/Subject | Depends on context |
3. Database Schema Changes
3.1 New Columns for books Table
-- Add storyteller fields (from campaigns)
ALTER TABLE books ADD COLUMN storyteller_name VARCHAR(255);
ALTER TABLE books ADD COLUMN storyteller_relationship VARCHAR(100);
-- Values: 'self', 'parent', 'grandparent', 'spouse', 'child', 'sibling', 'friend', 'other'
ALTER TABLE books ADD COLUMN storyteller_user_id UUID REFERENCES auth.users(id);
ALTER TABLE books ADD COLUMN storyteller_email VARCHAR(255);
ALTER TABLE books ADD COLUMN storyteller_phone VARCHAR(50);
ALTER TABLE books ADD COLUMN storyteller_notes TEXT;
-- Add gift fields (from campaigns)
ALTER TABLE books ADD COLUMN is_gift BOOLEAN DEFAULT FALSE;
ALTER TABLE books ADD COLUMN gift_message TEXT;
ALTER TABLE books ADD COLUMN gift_recipient_name VARCHAR(255);
ALTER TABLE books ADD COLUMN gift_recipient_email VARCHAR(255);
ALTER TABLE books ADD COLUMN gift_status VARCHAR(50) DEFAULT 'pending';
-- Values: 'pending', 'sent', 'delivered', 'accepted', 'declined'
ALTER TABLE books ADD COLUMN gift_delivery_date TIMESTAMP;
-- Add project management fields
ALTER TABLE books ADD COLUMN project_status VARCHAR(50) DEFAULT 'setup';
-- Values: 'setup', 'collecting', 'editing', 'designing', 'ready', 'published'
ALTER TABLE books ADD COLUMN setup_step VARCHAR(50) DEFAULT 'template';
ALTER TABLE books ADD COLUMN setup_progress JSONB DEFAULT '{}';
ALTER TABLE books ADD COLUMN goal_stories INTEGER DEFAULT 10;
ALTER TABLE books ADD COLUMN completed_stories INTEGER DEFAULT 0;
-- Add notification settings
ALTER TABLE books ADD COLUMN prompt_frequency VARCHAR(50) DEFAULT 'weekly';
-- Values: 'daily', 'weekly', 'biweekly', 'monthly', 'manual'
ALTER TABLE books ADD COLUMN notification_settings JSONB DEFAULT '{
"email_enabled": true,
"sms_enabled": false,
"push_enabled": false,
"reminder_day": "sunday",
"reminder_time": "10:00"
}';
-- Add creator relationship
ALTER TABLE books ADD COLUMN creator_relationship VARCHAR(100);
-- Values: 'self', 'family_member', 'gift_giver', 'collaborator'3.2 Update stories Table
-- Add book_id column (will replace campaign_id)
ALTER TABLE stories ADD COLUMN book_id UUID REFERENCES books(id);
-- Create index for performance
CREATE INDEX idx_stories_book_id ON stories(book_id);
-- Update check constraint to require one of book_id or campaign_id (transition)
-- Eventually remove campaign_id requirement3.3 Deprecation Plan for campaigns Table
Phase 1: Add new columns to books, support both Phase 2: Migrate existing data (if any production data exists) Phase 3: Update all code to use books Phase 4: Drop campaigns table
Since this is a new app, we can skip phases 1-2 and go directly to the new schema.
3.4 RLS Policy Updates
-- Books: Users can see their own books or family-shared books
CREATE POLICY "Users can view own and family books"
ON books FOR SELECT
USING (
user_id = auth.uid()
OR family_group_id IN (
SELECT family_group_id FROM family_members WHERE user_id = auth.uid()
)
);
-- Stories: Users can see stories in books they can access
CREATE POLICY "Users can view stories in accessible books"
ON stories FOR SELECT
USING (
user_id = auth.uid()
OR book_id IN (
SELECT id FROM books WHERE
user_id = auth.uid()
OR family_group_id IN (
SELECT family_group_id FROM family_members WHERE user_id = auth.uid()
)
)
);
-- Family members can edit based on permissions
CREATE POLICY "Family members can edit with permission"
ON stories FOR UPDATE
USING (
user_id = auth.uid()
OR book_id IN (
SELECT book_id FROM family_book_permissions
WHERE family_group_id IN (
SELECT family_group_id FROM family_members WHERE user_id = auth.uid()
)
AND auth.uid() = ANY(can_edit_members)
)
);4. Frontend Route Changes
4.1 Route Removal (campaigns β books)
| Old Route | New Route | Action |
|---|---|---|
/campaigns | /books | Redirect |
/campaigns/create | /books/new | Merge wizard |
/campaigns/[id] | /books/[id] | Enhance book dashboard |
/campaigns/[id]/stories | /books/[id]/stories | Move |
/campaigns/[id]/stories/new | /books/[id]/stories/new | Move |
/campaigns/[id]/stories/[id] | /books/[id]/stories/[id] | Move |
/campaigns/[id]/stories/[id]/edit | /books/[id]/stories/[id]/edit | Move |
/campaigns/[id]/ai/voice | /books/[id]/record | Voice recording hub (book-scoped) |
/campaigns/[id]/ai/photo | /books/[id]/conversations | AI conversation hub (book-scoped) |
/campaigns/[id]/import/voice | /books/[id]/import | Content import |
4.2 New Required Routes
/books/[id]/stories β Stories list (chapters)
/books/[id]/stories/new β Create story with template prompts
/books/[id]/stories/[sid] β View story in book context
/books/[id]/stories/[sid]/edit β Edit story (uses EnhancedEditorShell)
/books/[id]/record β Voice recording hub (book-scoped for RAG)
/books/[id]/conversations β AI conversation hub (book-scoped for RAG)
/books/[id]/import β Import content
/books/[id]/settings β Project settings
/books/[id]/share β Sharing & family permissionsWhy book-scoped? Recording and AI conversations are scoped to a specific book so the RAG system can use the bookβs existing stories as context. This provides more relevant AI suggestions and maintains conversational continuity.
5. Component Migration
5.1 Campaign Components to Migrate
| Component | Action | Notes |
|---|---|---|
Step0RoleSelection.tsx | Merge into book wizard | Creator relationship |
Step1.tsx (Storyteller info) | Merge into book wizard | Storyteller details |
Step2.tsx (Template) | Already exists in books | Template selection |
Step3.tsx (Goals) | Merge into book wizard | Story goals |
Step4.tsx (Schedule) | Merge into book wizard | Notification settings |
Step5.tsx (Review) | Merge into book wizard | Review step |
GiftDetailsStep.tsx | Merge into book wizard | Gift flow |
GiftMessageStep.tsx | Merge into book wizard | Gift message |
PaymentStep.tsx | Keep separate | Payment flow |
FamilyMembersStep.tsx | Merge/enhance | Family invitation |
InfoStep.tsx | Review and merge | Additional info |
5.2 Book Wizard Enhancement
The enhanced book creation wizard will have these steps:
Step 1: Choose Your Path
- "I'm writing my own story" (self)
- "I'm capturing someone else's story" (family member)
- "I'm giving this as a gift" (gift)
Step 2: About the Storyteller (if not self)
- Name
- Relationship to you
- Contact info (optional)
Step 3: Choose a Template
- Template gallery
- Template preview
- Chapter/prompt preview
Step 4: Book Details
- Title
- Description
- Cover style preference
Step 5: Set Your Goals
- Number of stories
- Target completion date
Step 6: Reminders (optional)
- Frequency
- Method (email/SMS)
Step 7: Review & Start
- Summary
- Start collecting stories button5.3 Shared Components
These components work for both books and stories and need no changes:
EnhancedEditorShell.tsx- Rich text editorVoiceRecordingInterface.tsx- Voice captureAIAssistant.tsx- AI featuresConfirmationModal.tsx- ConfirmationsToast.tsx- Notifications
6. Family Access Model
6.1 Access Levels
| Level | Can View | Can Comment | Can Edit | Can Delete | Can Invite |
|---|---|---|---|---|---|
| Owner | Yes | Yes | Yes | Yes | Yes |
| Editor | Yes | Yes | Yes | No | No |
| Contributor | Yes | Yes | Own only | Own only | No |
| Viewer | Yes | No | No | No | No |
6.2 Family Book Sharing Flow
1. Owner creates book β Assigned to family_group_id (optional)
2. Owner shares with family:
- Click "Share" button
- Select family members
- Choose permission level (viewer/contributor/editor)
- Send invitation
3. Family member receives:
- Email notification
- In-app notification
- Book appears in their "Shared with Me" section
4. Family member can:
- View book and stories
- Add their own stories (if contributor+)
- Edit any story (if editor)
- See real-time updates6.3 Storyteller vs Creator
| Scenario | Creator | Storyteller | Access |
|---|---|---|---|
| Writing own memoir | User A | User A | Full |
| Capturing parentβs story | User A | User Aβs parent | Creator: Full, Storyteller: View |
| Storyteller has account | User A | User B | Both can edit |
| Gift book | User A (gift giver) | User B (recipient) | Recipient becomes owner |
6.4 Database Support
-- Family book permissions already exist
-- family_book_permissions.can_edit_members[]
-- family_book_permissions.can_contribute_members[]
-- family_book_permissions.can_comment_members[]
-- Add visibility levels
ALTER TABLE family_book_permissions
ADD CONSTRAINT check_visibility
CHECK (visibility IN ('private', 'family', 'public'));7. Onboarding Flow Design
7.1 First-Time User Journey
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Welcome Screen β
β β
β "Ready to preserve your story?" β
β β
β [Start My First Book] β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Who is this book for? β
β β
β βββββββββββββββββββ βββββββββββββββββββ ββββββββββββββββ β
β β Myself β β A Family β β A Gift β β
β β β β Member β β β β
β β "I want to β β "I want to β β "I want to β β
β β write my β β capture my β β give the β β
β β own story" β β parent's or β β gift of β β
β β β β grandparent's β β memories" β β
β β β β memories" β β β β
β βββββββββββββββββββ βββββββββββββββββββ ββββββββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Choose Your Template β
β β
β Templates provide structure and prompts to guide your β
β storytelling. Choose one that fits your book's purpose. β
β β
β βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
β β Life β β Family β β War & β β Custom β β
β β Story β β History β β Service β β β β
β βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
β β
β Selected: Life Story Memoir β
β - 12 chapters covering childhood to present β
β - 50+ guided prompts β
β - Photo integration β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Give Your Book a Title β
β β
β ββββββββββββββββββββββββββββββββββββββββββββ β
β β Mom's Life Story β β
β ββββββββββββββββββββββββββββββββββββββββββββ β
β β
β You can always change this later. β
β β
β [Continue] β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β You're All Set! β
β β
β Your book "Mom's Life Story" is ready. β
β β
β What would you like to do first? β
β β
β βββββββββββββββββββββββββββ βββββββββββββββββββββββββββ β
β β π Write a Story β β ποΈ Record a Story β β
β β β β β β
β β Use our guided β β Speak your memories β β
β β prompts to write β β and we'll transcribe β β
β βββββββββββββββββββββββββββ βββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββ βββββββββββββββββββββββββββ β
β β π View Prompts β β βοΈ Book Settings β β
β β β β β β
β β See all the β β Customize your β β
β β template prompts β β book settings β β
β βββββββββββββββββββββββββββ βββββββββββββββββββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ7.2 Template-Informed Prompts
When user creates a new story, the template provides relevant prompts:
Template: "Life Story Memoir"
Chapter: "Early Childhood"
Suggested Prompts:
1. "What is your earliest memory?"
2. "Where did you grow up? Describe your childhood home."
3. "Who were the most important people in your early life?"
4. "What games did you play as a child?"
5. "What was your neighborhood like?"
[Choose a prompt] or [Write freely]8. User Journey Scenarios
8.1 Scenario A: Solo Memoir Writer
User: Sarah, 68, writing her own life story
1. Creates account
2. Starts first book: "I'm writing my own story"
3. Chooses "Life Story Memoir" template
4. Titles it "My Journey"
5. Sees template prompts organized by life stage
6. Writes first story: "My Childhood Home"
7. Story automatically becomes Chapter 1
8. Continues adding stories over weeks
9. When ready, designs cover and publishesKey Points:
- storyteller_user_id = user_id (same person)
- creator_relationship = βselfβ
- Template prompts guide her writing
8.2 Scenario B: Family Historian
User: Mike, 45, capturing his momβs stories
1. Creates account
2. Starts first book: "I'm capturing someone else's story"
3. Enters mom's info: "Helen", relationship: "parent"
4. Chooses "Family History" template
5. Invites mom to view/contribute (optional)
6. Records voice interviews with mom
7. Transcriptions become stories/chapters
8. Mike edits and organizes
9. Shares with siblings for contributions
10. Publishes as family keepsakeKey Points:
- user_id = Mike
- storyteller_name = βHelenβ
- storyteller_relationship = βparentβ
- storyteller_user_id = Momβs user ID (if she joins)
- Family sharing enables sibling contributions
8.3 Scenario C: Gift Giver
User: Lisa, giving a memory book to her dad
1. Creates account
2. Starts first book: "I'm giving this as a gift"
3. Enters dad's info as recipient
4. Chooses "Life Story" template
5. Optionally pre-seeds with a few prompts/stories
6. Adds gift message
7. Purchases at checkout
8. Dad receives gift, creates account
9. Ownership transfers to dad
10. Dad continues adding stories
11. Lisa becomes a "contributor" if dad allowsKey Points:
- is_gift = true
- gift_recipient_name, gift_recipient_email
- gift_status tracks delivery
- Ownership transfer on acceptance
8.4 Scenario D: Collaborative Family Project
User: The Johnson family creating a multi-generational book
1. Grandma starts book: "Johnson Family History"
2. Shares with children and grandchildren
3. Each family member:
- Adds their own stories
- Comments on others' stories
- Uploads photos
4. Grandma (owner) organizes chapters
5. Family votes on cover design
6. Published as family heirloomKey Points:
- family_group_id links all members
- family_book_permissions controls access
- Multiple contributors, one owner
- Version history tracks changes
8.5 Scenario E: Switching Templates Mid-Project
User: John started with βQuick Memoirβ but wants more structure
1. John has 5 stories written
2. Goes to Book Settings
3. Clicks "Change Template"
4. Sees warning: "Your existing stories will be preserved"
5. Selects "Life Story Memoir"
6. System suggests: "These existing stories might fit these chapters..."
7. John confirms mapping
8. New prompts become available
9. Existing content preserved, just reorganizedKey Points:
- Template change doesnβt delete content
- AI suggests story-to-chapter mapping
- User confirms changes
9. API Changes
9.1 New/Modified Endpoints
// Book CRUD (enhanced)
POST /api/books // Create book with all new fields
GET /api/books // List user's books + family shared
GET /api/books/:id // Get book with storyteller info
PATCH /api/books/:id // Update book
DELETE /api/books/:id // Delete book
// Stories now under books
POST /api/books/:id/stories // Create story for book
GET /api/books/:id/stories // List book's stories
GET /api/books/:id/stories/:sid // Get story
PATCH /api/books/:id/stories/:sid // Update story
DELETE /api/books/:id/stories/:sid // Delete story
// Template prompts
GET /api/books/:id/prompts // Get template prompts for book
GET /api/books/:id/prompts/:pid // Get specific prompt
// Family sharing
POST /api/books/:id/share // Share book with family
GET /api/books/:id/permissions // Get sharing permissions
PATCH /api/books/:id/permissions // Update permissions
// Gift flow
POST /api/books/:id/gift/send // Send gift
POST /api/books/:id/gift/accept // Accept gift
GET /api/gifts/received // List received gifts
// Voice recording (moved)
POST /api/books/:id/recordings // Upload recording
GET /api/books/:id/recordings // List recordings
// Story duplication (NEW)
POST /api/stories/:id/duplicate // Duplicate story to another book
// Body: { target_book_id: string }
// Creates a copy with new ID, linked to target book9.2 Type Definitions
// Enhanced Book type
interface Book {
id: string;
user_id: string;
// Basic info
title: string;
subtitle?: string;
description?: string;
// Storyteller info (NEW)
storyteller_name?: string;
storyteller_relationship?: 'self' | 'parent' | 'grandparent' |
'spouse' | 'child' | 'sibling' |
'friend' | 'other';
storyteller_user_id?: string;
storyteller_email?: string;
storyteller_phone?: string;
storyteller_notes?: string;
// Creator info (NEW)
creator_relationship: 'self' | 'family_member' | 'gift_giver' | 'collaborator';
// Template & Content
template_id?: string;
story_ids: string[];
goal_stories: number;
completed_stories: number;
// Project status (NEW)
project_status: 'setup' | 'collecting' | 'editing' |
'designing' | 'ready' | 'published';
setup_step?: string;
setup_progress?: Record<string, any>;
// Notifications (NEW)
prompt_frequency: 'daily' | 'weekly' | 'biweekly' | 'monthly' | 'manual';
notification_settings?: {
email_enabled: boolean;
sms_enabled: boolean;
push_enabled: boolean;
reminder_day?: string;
reminder_time?: string;
};
// Gift (NEW)
is_gift: boolean;
gift_message?: string;
gift_recipient_name?: string;
gift_recipient_email?: string;
gift_status?: 'pending' | 'sent' | 'delivered' | 'accepted' | 'declined';
gift_delivery_date?: string;
// Family
family_group_id?: string;
// Publishing
author_name: string;
contributor_names: string[];
// ... existing publishing fields
created_at: string;
updated_at: string;
}
// Updated Story type
interface Story {
id: string;
book_id: string; // NEW - replaces campaign_id
user_id: string;
title: string;
content: string;
prompt?: string; // Which template prompt was used
// Derived from books.story_ids index
chapter_number?: number;
word_count: number;
status: 'draft' | 'reviewed' | 'approved' | 'published';
// ... existing fields
}9.5 Placeholder Stories Feature (NEW)
When a user selects a template, the system automatically creates placeholder stories based on the template structure. This gives users a head start and shows them what the finished book could look like.
How It Works
User selects "Life Story Memoir" template
β
System creates book with:
- title: "[Storyteller's Name]'s Life Story"
- template_id: "life-story-memoir"
- story_ids: [] (initially empty)
β
System creates placeholder stories:
- "Early Childhood" (placeholder, status: 'placeholder')
- "Growing Up" (placeholder)
- "School Years" (placeholder)
- "First Job" (placeholder)
- ... (based on template chapters)
β
User sees book with placeholder chapters
Can click any to start writing/recordingPlaceholder Story Schema
interface Story {
// ... existing fields
// NEW: Placeholder support
is_placeholder: boolean; // True for auto-created placeholders
placeholder_prompt?: string; // The template prompt for this placeholder
template_chapter_index?: number; // Position in template
}Database Changes
-- Add placeholder fields to stories
ALTER TABLE stories ADD COLUMN is_placeholder BOOLEAN DEFAULT FALSE;
ALTER TABLE stories ADD COLUMN placeholder_prompt TEXT;
ALTER TABLE stories ADD COLUMN template_chapter_index INTEGER;Placeholder Story Behavior
| State | Display | Actions |
|---|---|---|
is_placeholder = true, empty content | Shows as βStart this chapterβ card | Click to edit, auto-removes placeholder flag |
is_placeholder = true, has content | Shows as draft | Continue editing |
is_placeholder = false | Normal story | Full editing |
User Can:
- Keep placeholder and fill it in
- Remove unwanted placeholders
- Reorder placeholders
- Add custom stories between placeholders
9.6 Story Duplication Feature (NEW)
Stories can be duplicated to other books. This is simpler than sharing/linking and gives users full control.
Use Cases
- Reuse content: User has a great story in Book A, wants it in Book B too
- Templates: Create a βmasterβ story and duplicate as starting point
- Family sharing: Duplicate a story to include in a relativeβs book
Duplication Flow
User viewing Story A in Book X
β
Clicks "Duplicate to another book"
β
Modal shows list of user's other books
β
User selects Book Y
β
System creates Story A' in Book Y:
- New UUID
- Same title (with " (Copy)" suffix, optional)
- Same content
- Links to Book Y
- user_id = current user
- is_duplicate = true
- source_story_id = Story A's ID
β
User can now edit Story A' independentlyAPI Endpoint
// POST /api/stories/:id/duplicate
interface DuplicateStoryRequest {
target_book_id: string;
include_copy_suffix?: boolean; // Default: true
copy_images?: boolean; // Default: true
}
interface DuplicateStoryResponse {
success: boolean;
new_story: Story;
message: string;
}Database Changes
-- Track story duplications
ALTER TABLE stories ADD COLUMN is_duplicate BOOLEAN DEFAULT FALSE;
ALTER TABLE stories ADD COLUMN source_story_id UUID REFERENCES stories(id);
-- Index for finding duplicates
CREATE INDEX idx_stories_source ON stories(source_story_id) WHERE source_story_id IS NOT NULL;Duplicate Behavior
- Independent: Changes to original donβt affect copy
- Attribution: Source story ID tracked for reference
- Images: Optionally copy associated images
- Permissions: Duplicate inherits permissions from target book
10. Data Migration Strategy
Note: All database migrations will be executed using Supabase MCP tools (
apply_migration,execute_sql). No raw SQL files needed.
10.1 For New App (Clean Slate)
Since this is a new app without production data:
- Drop
campaignstable via Supabase MCP (after ensuring no dependencies) - Enhance
bookstable with new columns viaapply_migration - Update
storiestable to usebook_idviaapply_migration - Remove
campaign_idfrom all tables - Update all RLS policies via
apply_migration
All schema changes will be applied directly to production using the MCP tools rather than creating local migration files.
10.2 If Migration Needed (Future Reference)
-- Step 1: Add new columns to books
-- (SQL from section 3.1)
-- Step 2: Copy data from campaigns to books
INSERT INTO books (
id, user_id, title, description,
storyteller_name, storyteller_relationship, storyteller_user_id,
storyteller_email, storyteller_phone, storyteller_notes,
template_id, goal_stories,
is_gift, gift_message, gift_recipient_name, gift_recipient_email,
gift_status, gift_delivery_date,
project_status, setup_step, setup_progress,
prompt_frequency, notification_settings,
family_group_id
)
SELECT
gen_random_uuid(), creator_id, title, description,
storyteller_name, user_role, storyteller_user_id,
storyteller_email, storyteller_phone, storyteller_notes,
template_id, goal_stories,
is_gift, gift_message, gift_recipient_name, gift_recipient_email,
gift_status, gift_delivery_date,
status, setup_step, setup_progress,
prompt_frequency, '{"email_enabled": true}'::jsonb,
family_group_id
FROM campaigns;
-- Step 3: Update stories to reference new books
UPDATE stories s
SET book_id = (
SELECT b.id FROM books b
JOIN campaigns c ON b.title = c.title AND b.user_id = c.creator_id
WHERE c.id = s.campaign_id
)
WHERE s.campaign_id IS NOT NULL;
-- Step 4: Drop campaign_id from stories
ALTER TABLE stories DROP COLUMN campaign_id;
-- Step 5: Drop campaigns table
DROP TABLE campaigns CASCADE;11. Risk Analysis
11.1 Technical Risks
| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| Breaking existing features | High | Medium | Comprehensive testing |
| RLS policy errors | High | Medium | Test each scenario |
| Missing edge cases | Medium | Medium | User journey testing |
| Performance degradation | Medium | Low | Index optimization |
11.2 UX Risks
| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| Confusion with new terms | Medium | Medium | Clear onboarding |
| Lost user mental model | Medium | Low | Gradual transition |
| Feature discovery issues | Low | Medium | Guided tours |
11.3 Business Risks
| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| Longer onboarding | Low | Medium | Streamlined wizard |
| Gift flow complexity | Medium | Low | Dedicated flow |
12. Implementation Phases
Phase 1: Database Schema (Week 1)
- Add new columns to
bookstable - Add
book_idtostoriestable - Create new indexes
- Update RLS policies
- Drop
campaignstable (if no data)
Phase 2: Core API (Week 1-2)
- Update book CRUD endpoints
- Update story endpoints for book_id
- Add template prompt endpoints
- Add sharing/permission endpoints
- Deprecate campaign endpoints
Phase 3: Book Creation Wizard (Week 2-3)
- Create new wizard steps
- Merge campaign wizard logic
- Implement template-first flow
- Add storyteller info capture
- Add gift flow integration
- Implement placeholder stories auto-creation
Phase 4: Story Management (Week 3)
- Move
/campaigns/[id]/storiesto/books/[id]/stories - Update story creation with book context
- Add template prompt integration
- Update EnhancedEditorShell for book context
- Add story duplication feature
- Add placeholder story UI (empty state cards)
Phase 5: Family Features (Week 4)
- Implement sharing UI
- Add permission management
- Create βShared with Meβ view
- Add family activity feed
Phase 6: Polish & Testing (Week 4-5)
- Add route redirects
- Comprehensive testing
- Performance optimization
- Documentation update
Appendix A: Design Decisions (RESOLVED)
All key decisions have been made. See βDesign Decisionsβ table at the top of this document.
| # | Question | Decision | Implementation Notes |
|---|---|---|---|
| 1 | UI Terminology | Book | Simple, intuitive. No βProjectβ suffix needed. |
| 2 | Template Change | Allowed | Preserve content, show warning, suggest storyβchapter mapping |
| 3 | Gift Auto-Add | Yes | Giver becomes contributor when recipient accepts |
| 4 | Voice Recording | Book-scoped | Recording hub at /books/[id]/record - context for RAG |
| 5 | AI Conversations | Book-scoped | Conversations hub at /books/[id]/conversations - RAG context |
| 6 | AI Prompts | Template-specific | Each template provides its own prompt set |
| 7 | Story Sharing | Duplicate only | No linking. Stories copied between books. Simpler. |
| 8 | Storyteller Auto-Link | Yes | If storyteller creates account with matching email |
| 9 | Family Defaults | Weekly updates ON | Family members get weekly digest by default |
| 10 | Placeholder Stories | Auto-created | Template selection creates placeholder chapters |
Appendix B: File Changes Summary
Files to Delete
/app/campaigns/*(all 27 files - clean slate, app never live)
Files to Create
/app/books/[id]/stories/page.tsx- Story list for book/app/books/[id]/stories/new/page.tsx- Create story in book/app/books/[id]/stories/[sid]/page.tsx- View story/app/books/[id]/stories/[sid]/edit/page.tsx- Edit story/app/books/[id]/record/page.tsx- Voice recording hub (book-scoped)/app/books/[id]/conversations/page.tsx- AI conversation hub (book-scoped)/app/books/[id]/share/page.tsx- Sharing permissions/app/books/[id]/settings/page.tsx- Book settings/app/books/[id]/import/page.tsx- Content import
Files to Modify
/app/books/new/page.tsx- Enhanced wizard with template-first flow/app/books/page.tsx- Updated dashboard/app/books/[id]/page.tsx- Book project view/types/books.ts- Updated types with storyteller fields/lib/supabase/*- Updated queries for book_id
Appendix C: RAG Context Architecture
Why Book-Scoped Recording & Conversations?
By scoping voice recordings and AI conversations to a specific book, we enable powerful RAG (Retrieval-Augmented Generation) capabilities:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Book: "Mom's Life Story" β
β β
β βββββββββββββββββββ βββββββββββββββββββ β
β β Stories β β Recordings β β
β β - Childhood β β - Interview 1 β β
β β - School Years β β - Interview 2 β β
β β - First Job β β - Photo Review β β
β ββββββββββ¬βββββββββ ββββββββββ¬βββββββββ β
β β β β
β ββββββββββ¬ββββββββββββ β
β βΌ β
β βββββββββββββββββββ β
β β RAG Vector DB β β Context for AI β
β β (Book-scoped) β β
β ββββββββββ¬βββββββββ β
β β β
β βΌ β
β βββββββββββββββββββ β
β β AI Conversation β β
β β β β
β β "What else do β β
β β you remember β β AI knows this is about β
β β about your β Mom, childhood, her school β
β β school days?" β β
β βββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββBenefits
| Benefit | Description |
|---|---|
| Contextual Prompts | AI suggests prompts based on whatβs already been covered |
| Continuity | βLast time you mentioned X, tell me more about thatβ |
| Gap Detection | AI identifies missing chapters from template |
| Deduplication | AI notices when user repeats a story |
| Personalization | Uses names, places, dates from existing stories |
| Better Transcription | Voice recognition improves with known vocabulary |
Implementation Notes
- Each book has its own vector embeddings in the RAG database
- Recordings are transcribed and indexed per book
- AI conversations reference book context for better responses
- Templates provide structure, but RAG fills in the details
Technical Implementation
For detailed RAG implementation including schema, API design, and performance analysis, see:
Contextual Memory & RAG Architecture Research
Key decisions from research:
- Supabase pgvector - Already approved, zero additional cost
- OpenAI text-embedding-3-small - $0.02/1M tokens, 1536 dimensions
- HNSW indexes - ~25ms latency at 100K vectors
- Hybrid search - pg_trgm (keyword) + pgvector (semantic)
- Database foundation - Already implemented (migrations applied Nov 2024)
Integration with Book-Scoped Architecture: The existing RAG implementation searches across all user content. For book-scoped context:
- Add
book_idfilter tosearch_unified_context()function - Generate embeddings on story save with book context
- Scope memory retrieval to current bookβs stories/recordings
Appendix D: Checklist Before Implementation
- Review and approve this document
- Confirm no production data in campaigns table
- Confirm voice/AI editor code is preserved
- Identify any third-party integrations affected
- Plan for any scheduled jobs/crons using campaigns
- Prepare user communication (if existing users)