# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
**SkyDeck** is a slide deck creation and sharing platform built with Skykit. Users can create Notion-style block-based presentations about their projects and share them in a public gallery on The Skyscape.
## Development Commands
```bash
# Run locally
go run .
# Build
go build -o skydeck .
# Run with Docker
docker build -t skydeck .
docker run -p 5000:5000 skydeck
```
## Architecture
### Project Structure
```
skydeck/
├── main.go # Application entry point
├── controllers/
│ ├── decks.go # Deck CRUD, authentication
│ └── gallery.go # Public gallery and publishing
├── models/
│ ├── database.go # Database connection
│ ├── deck.go # Deck model with JSON content
│ └── session.go # User session management
└── views/
├── home.html # Public gallery landing
├── editor.html # Block editor UI
├── view.html # Read-only deck viewer
├── present.html # Fullscreen presentation mode
└── public/
└── scripts/
└── editor.js # Frontend block editor logic
```
### Core Concepts
| Concept | Location | Purpose |
|---------|----------|---------|
| **Deck** | Database | Presentation stored as JSON slides/blocks |
| **Slide** | Deck JSON | Container for blocks |
| **Block** | Slide JSON | Content unit (heading, text, code, image, list, quote, divider) |
| **Gallery** | Public | Published decks with author attribution |
### Route Handlers
**Editor & API:**
| Route | Method | Handler | Purpose |
|-------|--------|---------|---------|
| `/` | GET | home.html | Public gallery |
| `/editor` | GET | editor.html | New deck |
| `/editor/{id}` | GET | editor.html | Edit deck |
| `/deck/{id}` | GET | view.html | View published |
| `/deck/{id}/present` | GET | present.html | Slideshow mode |
| `/api/decks` | GET | listDecks | User's decks |
| `/api/decks` | POST | createDeck | Create new |
| `/api/decks/{id}` | GET | getDeck | Get content |
| `/api/decks/{id}` | PUT | updateDeck | Update |
| `/api/decks/{id}` | DELETE | deleteDeck | Delete |
**Publishing:**
| Route | Method | Handler | Purpose |
|-------|--------|---------|---------|
| `/api/decks/{id}/publish` | POST | publishDeck | Make public |
| `/api/decks/{id}/unpublish` | POST | unpublishDeck | Make private |
| `/api/gallery` | GET | listPublished | Gallery feed |
| `/api/gallery/{id}/fork` | POST | forkDeck | Copy deck |
### Models
**Deck** - Presentation stored in database:
```go
type Deck struct {
skykit.Model
OwnerID string // User ID
OwnerName string // Cached for gallery
OwnerHandle string
OwnerAvatar string
Title string
Description string
Content string // JSON slides/blocks
CoverImage string
IsPublished bool
PublishedAt time.Time
ViewCount int
}
```
**DeckContent** - Parsed JSON structure:
```go
type DeckContent struct {
Slides []Slide
Theme string // "dark" or "light"
AspectRatio string // "16:9" or "4:3"
}
type Slide struct {
ID string
Blocks []Block
}
type Block struct {
ID string
Type string // heading, text, code, image, list, quote, divider
Content string // For heading, text, code, quote
Level int // For heading (1-3)
Language string // For code
URL string // For image
Caption string // For image
Style string // For list (bullet, number)
Items []string // For list
Author string // For quote
}
```
### Frontend Architecture
**editor.js** handles:
- Slide management (add, remove, reorder)
- Block editing with multiple types
- Drag/drop reordering via Sortable.js
- CodeMirror integration for code blocks
- Auto-save with 1-second debounce
- Keyboard shortcuts
**Libraries:**
- TailwindCSS/DaisyUI 5 - UI components
- CodeMirror 5 - Code editing
- Sortable.js - Drag/drop
- Marked - Markdown preview
- Highlight.js - Code highlighting (view/present)
## Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| `PORT` | No | Server port (default: 5000) |
| `DB_NAME` | For replica | Database name |
| `DB_URL` | For replica | LibSQL primary URL |
| `DB_TOKEN` | For replica | Database JWT token |
| `APP_ID` | OAuth | OAuth client ID |
| `OAUTH_CLIENT_SECRET` | OAuth | OAuth client secret |
## Security Considerations
### Authentication
- All editor/API routes require authentication via Skykit OAuth
- Public gallery routes are read-only
- Decks are isolated per user (OwnerID filter)
### Input Validation
- Deck content size limited (10MB)
- JSON content validated before storage
- Only owner can modify their decks
## Key Patterns
1. **Decks stored as JSON** - Full slide/block structure in Content field
2. **Cached author info** - Owner name/handle/avatar cached on deck for gallery display
3. **Fork on copy** - Published decks can be forked (copied with fresh ID)
4. **Auto-save** - Changes saved after 1 second of inactivity
5. **Presentation mode** - Fullscreen slideshow with keyboard navigation
## Block Types
| Type | Properties | Description |
|------|------------|-------------|
| heading | content, level (1-3) | Title text |
| text | content | Paragraph text |
| code | content, language | Code block with syntax highlighting |
| image | url, caption | Image with optional caption |
| list | style, items[] | Bullet or numbered list |
| quote | content, author | Blockquote with attribution |
| divider | (none) | Horizontal rule |