# Task 3.3: Create DynamoDB Table Schemas ## Overview This task implements all DynamoDB table creation methods for the Custom Start Page application. The implementation follows the schema design specified in the design document and addresses Requirements 8.3, 8.4, 8.5, and 11.6. ## Implementation Details ### Tables Created 1. **Users Table** - Partition Key: `user_id` (String) - No GSI - Stores user authentication and profile data 2. **Pages Table** - Partition Key: `user_id` (String) - Sort Key: `page_id` (String) - No GSI - Stores page configurations for each user 3. **Widgets Table** - Partition Key: `page_id` (String) - Sort Key: `widget_id` (String) - No GSI - Stores widget configurations for each page 4. **Bookmarks Table** - Partition Key: `widget_id` (String) - Sort Key: `bookmark_id` (String) - GSI: **UserBookmarksIndex** - Partition Key: `user_id` (String) - Sort Key: `created_at` (Number) - Projection: ALL - Stores bookmark data with support for cross-widget queries 5. **Notes Table** - Partition Key: `widget_id` (String) - Sort Key: `note_id` (String) - GSI: **UserNotesIndex** - Partition Key: `user_id` (String) - Sort Key: `created_at` (Number) - Projection: ALL - Stores note content with rich format support 6. **TagAssociations Table** - Partition Key: `item_id` (String) - Sort Key: `tag_name` (String) - GSI: **TagItemsIndex** - Partition Key: `tag_name` (String) - Sort Key: `user_id` (String) - Projection: INCLUDE (item_id, item_type, created_at) - Enables efficient tag-based filtering and queries 7. **Groups Table** - Partition Key: `widget_id` (String) - Sort Key: `group_id` (String) - No GSI - Stores bookmark group configurations 8. **SharedItems Table** - Partition Key: `share_id` (String) - GSI: **UserSharesIndex** - Partition Key: `user_id` (String) - Sort Key: `created_at` (Number) - Projection: INCLUDE (share_id, item_id, item_type, access_count) - Stores shareable links for bookmarks and notes 9. **Preferences Table** - Partition Key: `user_id` (String) - No GSI - Stores user preferences and settings ### Key Design Features - **Billing Mode**: All tables use Pay-Per-Request (on-demand) billing for cost efficiency - **Idempotency**: All table creation methods check if the table exists before creating - **Wait for Active**: All methods wait for tables to become active before returning - **Error Handling**: Comprehensive error handling with descriptive error messages - **Composite Keys**: Used where needed for efficient querying (Pages, Widgets, Bookmarks, Notes, etc.) - **GSI Strategy**: Global Secondary Indexes enable efficient cross-partition queries for tags and user-scoped data ### Access Patterns Supported 1. Get all pages for a user (Query Pages by user_id) 2. Get all widgets for a page (Query Widgets by page_id) 3. Get all bookmarks for a widget (Query Bookmarks by widget_id) 4. Get all bookmarks for a user (Query UserBookmarksIndex by user_id) 5. Get all notes for a user (Query UserNotesIndex by user_id) 6. Get all items with a specific tag (Query TagItemsIndex by tag_name + user_id) 7. Get all tags for an item (Query TagAssociations by item_id) 8. Get all groups for a widget (Query Groups by widget_id) 9. Get shared item by share ID (GetItem SharedItems by share_id) 10. Get all shares for a user (Query UserSharesIndex by user_id) ## Files Modified 1. **internal/storage/dynamodb.go** - Added `CreatePagesTable()` method - Added `CreateWidgetsTable()` method - Added `CreateBookmarksTable()` method with UserBookmarksIndex GSI - Added `CreateNotesTable()` method with UserNotesIndex GSI - Added `CreateTagAssociationsTable()` method with TagItemsIndex GSI - Added `CreateGroupsTable()` method - Added `CreateSharedItemsTable()` method with UserSharesIndex GSI - Added `CreatePreferencesTable()` method 2. **cmd/init-db/main.go** - Updated to call all table creation methods - Added loop to create all tables with status reporting - Added summary output showing all created tables 3. **internal/storage/dynamodb_test.go** - Added `TestCreateUsersTable()` - verifies Users table schema - Added `TestCreatePagesTable()` - verifies composite key schema - Added `TestCreateWidgetsTable()` - verifies composite key schema - Added `TestCreateBookmarksTable()` - verifies GSI configuration - Added `TestCreateNotesTable()` - verifies GSI configuration - Added `TestCreateTagAssociationsTable()` - verifies GSI with INCLUDE projection - Added `TestCreateGroupsTable()` - verifies composite key schema - Added `TestCreateSharedItemsTable()` - verifies GSI configuration - Added `TestCreatePreferencesTable()` - verifies simple key schema - Added `TestCreateAllTables()` - integration test for all tables ## Testing All tests are designed to: - Skip gracefully when DynamoDB local is not available - Verify table existence and schema correctness - Test idempotency (calling create twice should not error) - Verify key schemas (partition and sort keys) - Verify GSI configurations (key schema, projection type) To run tests with DynamoDB local: ```bash # Start DynamoDB local make db-start # Run tests make test # Or run specific tests /usr/local/go/bin/go test -v ./internal/storage -run TestCreate ``` ## Usage To initialize all tables: ```bash # Build the init-db command /usr/local/go/bin/go build -o bin/init-db cmd/init-db/main.go # Run against local DynamoDB ./bin/init-db -endpoint http://localhost:8000 # Run against AWS DynamoDB (uses default AWS credentials) ./bin/init-db -endpoint "" ``` ## Requirements Validation - ✅ **Requirement 8.3**: Storage service stores page configurations - ✅ **Requirement 8.4**: Storage service stores widget configurations - ✅ **Requirement 8.5**: Storage service stores user preferences - ✅ **Requirement 11.6**: Data model and indexing strategy for tags defined - TagAssociations table with TagItemsIndex GSI - Supports one-to-many relationships - Enables efficient tag-based queries ## Next Steps The table schemas are now ready for use. The next tasks will implement: - Storage layer CRUD operations for each table - Service layer business logic - HTTP handlers for API endpoints