phase 5
This commit is contained in:
@@ -1,506 +0,0 @@
|
||||
# Quickstart Guide: Reference Board Viewer
|
||||
|
||||
**Last Updated:** 2025-11-02
|
||||
**For:** Developers starting implementation
|
||||
**Prerequisites:** Nix installed, basic Git knowledge
|
||||
|
||||
## Overview
|
||||
|
||||
This guide will get you from zero to a running development environment for the Reference Board Viewer in under 10 minutes.
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Clone and Enter Development Environment
|
||||
|
||||
```bash
|
||||
# Clone repository (if not already)
|
||||
cd /home/jawz/Development/Projects/personal/webref
|
||||
|
||||
# Enter Nix development shell (from flake.nix)
|
||||
nix develop
|
||||
|
||||
# Verify tools are available
|
||||
python --version # Python 3.12
|
||||
node --version # Node.js 20+
|
||||
psql --version # PostgreSQL client
|
||||
ruff --version # Python linter
|
||||
```
|
||||
|
||||
**What this does:** `flake.nix` provides all dependencies (Python, Node.js, PostgreSQL, MinIO, etc.)
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Initialize Database
|
||||
|
||||
```bash
|
||||
# Start PostgreSQL (in development)
|
||||
# Option A: Using Nix
|
||||
pg_ctl -D ./pgdata init
|
||||
pg_ctl -D ./pgdata start
|
||||
|
||||
# Option B: Using system PostgreSQL
|
||||
sudo systemctl start postgresql
|
||||
|
||||
# Create database
|
||||
createdb webref
|
||||
|
||||
# Run migrations (after backend setup)
|
||||
cd backend
|
||||
alembic upgrade head
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Set Up Backend (FastAPI)
|
||||
|
||||
```bash
|
||||
# Create backend directory
|
||||
mkdir -p backend
|
||||
cd backend
|
||||
|
||||
# Initialize uv project
|
||||
uv init
|
||||
|
||||
# Install dependencies (all verified in nixpkgs)
|
||||
uv add fastapi uvicorn sqlalchemy alembic pydantic \
|
||||
python-jose passlib pillow boto3 python-multipart \
|
||||
httpx pytest pytest-cov pytest-asyncio
|
||||
|
||||
# Create basic structure
|
||||
mkdir -p app/{auth,boards,images,database,api,core} tests
|
||||
|
||||
# Create main.py
|
||||
cat > app/main.py << 'EOF'
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
|
||||
app = FastAPI(title="Reference Board Viewer API")
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["http://localhost:5173"], # Vite dev server
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
@app.get("/")
|
||||
async def root():
|
||||
return {"message": "Reference Board Viewer API", "version": "1.0.0"}
|
||||
|
||||
@app.get("/health")
|
||||
async def health():
|
||||
return {"status": "healthy"}
|
||||
EOF
|
||||
|
||||
# Run development server
|
||||
uvicorn app.main:app --reload --port 8000
|
||||
|
||||
# Test: curl http://localhost:8000/
|
||||
```
|
||||
|
||||
**Verify:** Navigate to http://localhost:8000/docs to see auto-generated OpenAPI documentation.
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Set Up Frontend (Svelte + Konva)
|
||||
|
||||
```bash
|
||||
# Create frontend directory (in new terminal)
|
||||
cd /home/jawz/Development/Projects/personal/webref
|
||||
mkdir -p frontend
|
||||
cd frontend
|
||||
|
||||
# Initialize SvelteKit project
|
||||
npm create svelte@latest .
|
||||
# Choose: Skeleton project, Yes to TypeScript, Yes to ESLint, Yes to Prettier
|
||||
|
||||
# Install dependencies
|
||||
npm install
|
||||
npm install konva
|
||||
|
||||
# Create basic canvas component
|
||||
mkdir -p src/lib/canvas
|
||||
cat > src/lib/canvas/Board.svelte << 'EOF'
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import Konva from 'konva';
|
||||
|
||||
let container: HTMLDivElement;
|
||||
let stage: Konva.Stage;
|
||||
|
||||
onMount(() => {
|
||||
stage = new Konva.Stage({
|
||||
container: container,
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight
|
||||
});
|
||||
|
||||
const layer = new Konva.Layer();
|
||||
stage.add(layer);
|
||||
|
||||
const text = new Konva.Text({
|
||||
text: 'Reference Board Canvas',
|
||||
fontSize: 24,
|
||||
fill: 'black',
|
||||
x: 50,
|
||||
y: 50
|
||||
});
|
||||
|
||||
layer.add(text);
|
||||
layer.draw();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div bind:this={container} class="canvas-container"></div>
|
||||
|
||||
<style>
|
||||
.canvas-container {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
</style>
|
||||
EOF
|
||||
|
||||
# Update home page
|
||||
cat > src/routes/+page.svelte << 'EOF'
|
||||
<script>
|
||||
import Board from '$lib/canvas/Board.svelte';
|
||||
</script>
|
||||
|
||||
<Board />
|
||||
EOF
|
||||
|
||||
# Run development server
|
||||
npm run dev -- --open
|
||||
|
||||
# Verify: Browser opens to http://localhost:5173
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Start MinIO (Image Storage)
|
||||
|
||||
```bash
|
||||
# In new terminal
|
||||
mkdir -p ~/minio-data
|
||||
|
||||
# Start MinIO
|
||||
minio server ~/minio-data --console-address :9001
|
||||
|
||||
# Access console: http://localhost:9001
|
||||
# Default credentials: minioadmin / minioadmin
|
||||
|
||||
# Create bucket
|
||||
mc alias set local http://localhost:9000 minioadmin minioadmin
|
||||
mc mb local/webref
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Project Structure After Setup
|
||||
|
||||
```
|
||||
webref/
|
||||
├── backend/
|
||||
│ ├── app/
|
||||
│ │ ├── main.py ✅ Created
|
||||
│ │ ├── auth/
|
||||
│ │ ├── boards/
|
||||
│ │ ├── images/
|
||||
│ │ ├── database/
|
||||
│ │ └── core/
|
||||
│ ├── tests/
|
||||
│ ├── pyproject.toml ✅ Created by uv
|
||||
│ └── alembic.ini
|
||||
├── frontend/
|
||||
│ ├── src/
|
||||
│ │ ├── lib/
|
||||
│ │ │ └── canvas/
|
||||
│ │ │ └── Board.svelte ✅ Created
|
||||
│ │ └── routes/
|
||||
│ │ └── +page.svelte ✅ Created
|
||||
│ ├── package.json ✅ Created
|
||||
│ └── vite.config.js
|
||||
├── specs/
|
||||
│ └── 001-reference-board-viewer/
|
||||
│ ├── spec.md ✅ Complete
|
||||
│ ├── plan.md ✅ Complete
|
||||
│ ├── data-model.md ✅ Complete
|
||||
│ ├── tech-research.md ✅ Complete
|
||||
│ └── contracts/
|
||||
│ └── api.yaml ✅ Complete
|
||||
├── shell.nix ✅ Update needed
|
||||
└── flake.nix (To be created)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Commands Reference
|
||||
|
||||
### Backend
|
||||
```bash
|
||||
# All commands run inside nix develop shell
|
||||
|
||||
# Run API server
|
||||
cd backend && uvicorn app.main:app --reload
|
||||
|
||||
# Run tests
|
||||
cd backend && pytest
|
||||
|
||||
# Run with coverage
|
||||
cd backend && pytest --cov=app --cov-report=html
|
||||
|
||||
# Check linting
|
||||
cd backend && ruff check app/
|
||||
|
||||
# Format code
|
||||
cd backend && ruff format app/
|
||||
|
||||
# Run migrations
|
||||
cd backend && alembic upgrade head
|
||||
|
||||
# Create migration
|
||||
cd backend && alembic revision --autogenerate -m "description"
|
||||
```
|
||||
|
||||
### NixOS VM Integration Tests
|
||||
```bash
|
||||
# Run all tests (backend, full-stack, performance, security)
|
||||
nix flake check
|
||||
|
||||
# Run specific test
|
||||
nix build .#checks.x86_64-linux.backend-integration -L
|
||||
nix build .#checks.x86_64-linux.full-stack -L
|
||||
|
||||
# Interactive debugging
|
||||
nix build .#checks.x86_64-linux.backend-integration.driverInteractive
|
||||
./result/bin/nixos-test-driver
|
||||
```
|
||||
|
||||
### Frontend
|
||||
```bash
|
||||
# Run dev server
|
||||
npm run dev
|
||||
|
||||
# Run tests
|
||||
npm test
|
||||
|
||||
# Check types
|
||||
npm run check
|
||||
|
||||
# Lint
|
||||
npm run lint
|
||||
|
||||
# Build for production
|
||||
npm run build
|
||||
|
||||
# Preview production build
|
||||
npm run preview
|
||||
```
|
||||
|
||||
### Database
|
||||
```bash
|
||||
# Connect to database
|
||||
psql webref
|
||||
|
||||
# Backup database
|
||||
pg_dump webref > backup.sql
|
||||
|
||||
# Restore database
|
||||
psql webref < backup.sql
|
||||
|
||||
# Reset database
|
||||
dropdb webref && createdb webref
|
||||
alembic upgrade head
|
||||
```
|
||||
|
||||
### MinIO
|
||||
```bash
|
||||
# List buckets
|
||||
mc ls local/
|
||||
|
||||
# List files in bucket
|
||||
mc ls local/webref/
|
||||
|
||||
# Copy file to bucket
|
||||
mc cp file.jpg local/webref/originals/
|
||||
|
||||
# Remove file
|
||||
mc rm local/webref/originals/file.jpg
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Create `.env` file in backend/:
|
||||
|
||||
```bash
|
||||
# Database
|
||||
DATABASE_URL=postgresql://localhost/webref
|
||||
|
||||
# JWT Secret (generate with: openssl rand -hex 32)
|
||||
SECRET_KEY=your-secret-key-here
|
||||
ALGORITHM=HS256
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
||||
|
||||
# MinIO
|
||||
MINIO_ENDPOINT=localhost:9000
|
||||
MINIO_ACCESS_KEY=minioadmin
|
||||
MINIO_SECRET_KEY=minioadmin
|
||||
MINIO_BUCKET=webref
|
||||
MINIO_SECURE=false
|
||||
|
||||
# CORS
|
||||
CORS_ORIGINS=["http://localhost:5173"]
|
||||
|
||||
# File Upload
|
||||
MAX_FILE_SIZE=52428800 # 50MB
|
||||
MAX_BATCH_SIZE=524288000 # 500MB
|
||||
ALLOWED_MIME_TYPES=["image/jpeg","image/png","image/gif","image/webp","image/svg+xml"]
|
||||
```
|
||||
|
||||
Create `.env` in frontend/:
|
||||
|
||||
```bash
|
||||
# API endpoint
|
||||
VITE_API_URL=http://localhost:8000/api/v1
|
||||
|
||||
# Feature flags
|
||||
VITE_ENABLE_COMMENTS=true
|
||||
VITE_ENABLE_SLIDESHOW=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing the Setup
|
||||
|
||||
### 1. Backend Health Check
|
||||
```bash
|
||||
curl http://localhost:8000/health
|
||||
# Expected: {"status":"healthy"}
|
||||
```
|
||||
|
||||
### 2. API Documentation
|
||||
Navigate to: http://localhost:8000/docs
|
||||
|
||||
### 3. Frontend Canvas
|
||||
Navigate to: http://localhost:5173
|
||||
Should see: "Reference Board Canvas" text on grey background
|
||||
|
||||
### 4. Database Connection
|
||||
```bash
|
||||
psql webref -c "SELECT 1;"
|
||||
# Expected: (1 row)
|
||||
```
|
||||
|
||||
### 5. MinIO Console
|
||||
Navigate to: http://localhost:9001
|
||||
Login with: minioadmin / minioadmin
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Nix command not found"
|
||||
```bash
|
||||
# Install Nix
|
||||
curl -L https://nixos.org/nix/install | sh
|
||||
```
|
||||
|
||||
### "Port 8000 already in use"
|
||||
```bash
|
||||
# Find and kill process
|
||||
lsof -i :8000
|
||||
kill -9 <PID>
|
||||
```
|
||||
|
||||
### "PostgreSQL connection refused"
|
||||
```bash
|
||||
# Start PostgreSQL
|
||||
sudo systemctl start postgresql
|
||||
# Or using Nix:
|
||||
pg_ctl -D ./pgdata start
|
||||
```
|
||||
|
||||
### "npm install fails"
|
||||
```bash
|
||||
# Clear npm cache
|
||||
npm cache clean --force
|
||||
rm -rf node_modules package-lock.json
|
||||
npm install
|
||||
```
|
||||
|
||||
### "Python module not found"
|
||||
```bash
|
||||
# Reinstall with uv
|
||||
uv sync
|
||||
# Or exit and re-enter nix shell
|
||||
exit
|
||||
nix develop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Follow the plan:** See [plan.md](./plan.md) for 16-week implementation timeline
|
||||
2. **Implement authentication:** Week 2 tasks in plan
|
||||
3. **Set up database schema:** Use [data-model.md](./data-model.md) and Alembic
|
||||
4. **Implement API endpoints:** Use [contracts/api.yaml](./contracts/api.yaml) as reference
|
||||
5. **Build canvas components:** Follow Week 5-8 tasks
|
||||
|
||||
---
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Daily workflow:
|
||||
```bash
|
||||
# Morning
|
||||
cd webref
|
||||
nix develop
|
||||
cd backend && uvicorn app.main:app --reload &
|
||||
cd frontend && npm run dev &
|
||||
|
||||
# Work on features...
|
||||
|
||||
# Before commit
|
||||
cd backend && pytest && ruff check app/
|
||||
cd frontend && npm run check && npm run lint
|
||||
|
||||
# Commit
|
||||
git add .
|
||||
git commit -m "feat: description"
|
||||
```
|
||||
|
||||
### Weekly workflow:
|
||||
- Review plan.md progress
|
||||
- Update tests for new features
|
||||
- Check coverage: `pytest --cov`
|
||||
- Update documentation
|
||||
|
||||
---
|
||||
|
||||
## Resources
|
||||
|
||||
- **API Spec:** [contracts/api.yaml](./contracts/api.yaml)
|
||||
- **Data Model:** [data-model.md](./data-model.md)
|
||||
- **Tech Stack:** [tech-research.md](./tech-research.md)
|
||||
- **Nix Verification:** [VERIFICATION-COMPLETE.md](./VERIFICATION-COMPLETE.md)
|
||||
- **Full Plan:** [plan.md](./plan.md)
|
||||
|
||||
**External Docs:**
|
||||
- FastAPI: https://fastapi.tiangolo.com/
|
||||
- Svelte: https://svelte.dev/docs
|
||||
- Konva: https://konvajs.org/docs/
|
||||
- Alembic: https://alembic.sqlalchemy.org/
|
||||
- MinIO: https://min.io/docs/minio/linux/index.html
|
||||
|
||||
---
|
||||
|
||||
**Questions?** Check the specification in [spec.md](./spec.md) or plan in [plan.md](./plan.md).
|
||||
|
||||
**Ready to start?** Begin with Week 1 tasks in the implementation plan!
|
||||
|
||||
@@ -183,45 +183,45 @@ Implementation tasks for the Reference Board Viewer, organized by user story (fu
|
||||
**User Story:** Users must be able to add images to boards through multiple methods
|
||||
|
||||
**Independent Test Criteria:**
|
||||
- [ ] Users can upload via file picker
|
||||
- [ ] Users can drag-drop images
|
||||
- [ ] Users can paste from clipboard
|
||||
- [ ] Users can upload ZIP files (auto-extracted)
|
||||
- [ ] File validation rejects invalid files
|
||||
- [ ] Thumbnails generated automatically
|
||||
- [X] Users can upload via file picker
|
||||
- [X] Users can drag-drop images
|
||||
- [X] Users can paste from clipboard
|
||||
- [X] Users can upload ZIP files (auto-extracted)
|
||||
- [X] File validation rejects invalid files
|
||||
- [X] Thumbnails generated automatically
|
||||
|
||||
**Backend Tasks:**
|
||||
|
||||
- [ ] T076 [P] [US3] Create Image model in backend/app/database/models/image.py from data-model.md
|
||||
- [ ] T077 [P] [US3] Create BoardImage model in backend/app/database/models/board_image.py from data-model.md
|
||||
- [ ] T078 [P] [US3] Create image schemas in backend/app/images/schemas.py (ImageUpload, ImageResponse)
|
||||
- [ ] T079 [US3] Implement file validation in backend/app/images/validation.py (magic bytes, size, type)
|
||||
- [ ] T080 [US3] Implement image upload handler in backend/app/images/upload.py (streaming to MinIO)
|
||||
- [ ] T081 [US3] Implement thumbnail generation in backend/app/images/processing.py (Pillow resizing)
|
||||
- [ ] T082 [US3] Create image repository in backend/app/images/repository.py (metadata operations)
|
||||
- [ ] T083 [US3] Implement upload endpoint POST /boards/{id}/images in backend/app/api/images.py
|
||||
- [ ] T084 [US3] Implement ZIP extraction handler in backend/app/images/zip_handler.py
|
||||
- [ ] T085 [US3] Set up background task queue for thumbnail generation in backend/app/core/tasks.py
|
||||
- [ ] T086 [P] [US3] Write unit tests for file validation in backend/tests/images/test_validation.py
|
||||
- [ ] T087 [P] [US3] Write unit tests for thumbnail generation in backend/tests/images/test_processing.py
|
||||
- [ ] T088 [P] [US3] Write integration tests for upload endpoint in backend/tests/api/test_images.py
|
||||
- [X] T076 [P] [US3] Create Image model in backend/app/database/models/image.py from data-model.md
|
||||
- [X] T077 [P] [US3] Create BoardImage model in backend/app/database/models/board_image.py from data-model.md
|
||||
- [X] T078 [P] [US3] Create image schemas in backend/app/images/schemas.py (ImageUpload, ImageResponse)
|
||||
- [X] T079 [US3] Implement file validation in backend/app/images/validation.py (magic bytes, size, type)
|
||||
- [X] T080 [US3] Implement image upload handler in backend/app/images/upload.py (streaming to MinIO)
|
||||
- [X] T081 [US3] Implement thumbnail generation in backend/app/images/processing.py (Pillow resizing)
|
||||
- [X] T082 [US3] Create image repository in backend/app/images/repository.py (metadata operations)
|
||||
- [X] T083 [US3] Implement upload endpoint POST /boards/{id}/images in backend/app/api/images.py
|
||||
- [X] T084 [US3] Implement ZIP extraction handler in backend/app/images/zip_handler.py
|
||||
- [X] T085 [US3] Set up background task queue for thumbnail generation in backend/app/core/tasks.py
|
||||
- [X] T086 [P] [US3] Write unit tests for file validation in backend/tests/images/test_validation.py
|
||||
- [X] T087 [P] [US3] Write unit tests for thumbnail generation in backend/tests/images/test_processing.py
|
||||
- [X] T088 [P] [US3] Write integration tests for upload endpoint in backend/tests/api/test_images.py
|
||||
|
||||
**Frontend Tasks:**
|
||||
|
||||
- [ ] T089 [P] [US3] Create images API client in frontend/src/lib/api/images.ts
|
||||
- [ ] T090 [P] [US3] Create images store in frontend/src/lib/stores/images.ts
|
||||
- [ ] T091 [US3] Implement file picker upload in frontend/src/lib/components/upload/FilePicker.svelte
|
||||
- [ ] T092 [US3] Implement drag-drop zone in frontend/src/lib/components/upload/DropZone.svelte
|
||||
- [ ] T093 [US3] Implement clipboard paste handler in frontend/src/lib/utils/clipboard.ts
|
||||
- [ ] T094 [US3] Implement ZIP upload handler in frontend/src/lib/utils/zip-upload.ts
|
||||
- [ ] T095 [P] [US3] Create upload progress component in frontend/src/lib/components/upload/ProgressBar.svelte
|
||||
- [ ] T096 [P] [US3] Create upload error display in frontend/src/lib/components/upload/ErrorDisplay.svelte
|
||||
- [X] T089 [P] [US3] Create images API client in frontend/src/lib/api/images.ts
|
||||
- [X] T090 [P] [US3] Create images store in frontend/src/lib/stores/images.ts
|
||||
- [X] T091 [US3] Implement file picker upload in frontend/src/lib/components/upload/FilePicker.svelte
|
||||
- [X] T092 [US3] Implement drag-drop zone in frontend/src/lib/components/upload/DropZone.svelte
|
||||
- [X] T093 [US3] Implement clipboard paste handler in frontend/src/lib/utils/clipboard.ts
|
||||
- [X] T094 [US3] Implement ZIP upload handler in frontend/src/lib/utils/zip-upload.ts
|
||||
- [X] T095 [P] [US3] Create upload progress component in frontend/src/lib/components/upload/ProgressBar.svelte
|
||||
- [X] T096 [P] [US3] Create upload error display in frontend/src/lib/components/upload/ErrorDisplay.svelte
|
||||
- [ ] T097 [P] [US3] Write upload component tests in frontend/tests/components/upload.test.ts
|
||||
|
||||
**Infrastructure:**
|
||||
|
||||
- [ ] T098 [US3] Configure MinIO bucket creation in backend/app/core/storage.py
|
||||
- [ ] T099 [US3] Set up MinIO via Nix in flake.nix services configuration
|
||||
- [X] T098 [US3] Configure MinIO bucket creation in backend/app/core/storage.py
|
||||
- [X] T099 [US3] Set up MinIO via Nix in flake.nix services configuration
|
||||
|
||||
**Deliverables:**
|
||||
- Multi-method upload working
|
||||
|
||||
Reference in New Issue
Block a user