Modern Kanban ToDo app built with SvelteKit, Hasura GraphQL, and PostgreSQL.
- Node.js 18+ (recommended: use
nvm) - Docker & Docker Compose (for Hasura)
- Hasura CLI
- Claude Code with MCP servers (see MCP Setup below)
-
Node & Dependencies
# Optional: Use same Node version across devices nvm install && nvm use # Install dependencies npm ci # Windows troubleshooting (if needed) npm install --maxsockets=1
-
Environment Setup
# Copy and configure environment files cp .env.example .env cp hasura/.env.example hasura/.env cp .env.test.example .env.test # Edit .env files with your database credentials
-
Backend Setup
# Start Hasura cd hasura docker-compose up -d # Configure Hasura cp config.example.yaml config.yaml # Edit config.yaml with your admin password # Apply migrations and metadata hasura migrate apply --all-databases hasura metadata apply # Optional: Load seed data (creates test@test.com user) hasura seed apply # Open Hasura Console hasura console # Console opens at http://localhost:9695
-
Verify Installation
npm run check npm test -
Start Development
npm run dev # Opens at http://localhost:5173
MCP (Model Context Protocol) servers enhance Claude Code with browser automation, database access, and advanced problem-solving capabilities.
Required MCP Servers:
# 1. Playwright - Browser testing & console logs
claude mcp add playwright -- npx @playwright/mcp@latest
# 2. Sequential Thinking - Complex problem solving
claude mcp add sequential-thinking -- npx -y @modelcontextprotocol/server-sequential-thinking
# 3. Filesystem - Direct file operations (RECOMMENDED)
# Windows:
claude mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem C:/git/svelte-todo-kanban
# macOS/Linux:
claude mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem /path/to/svelte-todo-kanbanOptional MCP Servers:
# Context7 - Latest framework documentation
claude mcp add --transport http context7 https://mcp.context7.com/mcp/
# GitHub - Version control operations
claude mcp add --transport http github https://api.githubcopilot.com/mcp/claude mcp list
# Should show (✓ Connected):
# - playwright
# - sequential-thinking
# - filesystem
# - context7 (if installed)Once configured, MCP servers are automatically available in all Claude Code sessions:
- Playwright: Test features in browser, capture console logs, take UI snapshots
- Sequential Thinking: Plan complex features, analyze architecture decisions
- Filesystem: Bulk file operations, project-wide refactoring
- Context7: Get latest SvelteKit/Svelte 5 documentation
Example workflow:
# In Claude Code, you can now say:
"Use Playwright to test the drag-and-drop at localhost:5173"
"Use sequential thinking to plan the real-time collaboration feature"
"Use filesystem to rename all .svelte files to use new naming convention"Frontend: Svelte 5, SvelteKit, TypeScript, Tailwind CSS, shadcn-svelte
Backend: Hasura GraphQL, PostgreSQL
Auth: Auth.js with JWT tokens
Rich Text: svelte-tiptap (Markdown support planned)
Testing: Playwright (E2E), Vitest (unit/component)
i18n: sveltekit-i18n
src/
├── routes/
│ ├── [lang]/ # Language-based routing
│ └── api/ # Auth & file uploads
├── lib/
│ ├── components/
│ │ ├── todo/ # Todo components
│ │ ├── listBoard/ # Board/list components
│ │ └── ui/ # Shared UI (shadcn)
│ ├── stores/ # State management
│ ├── graphql/
│ │ ├── client.ts # GraphQL client
│ │ ├── documents.ts # All queries/mutations
│ │ └── generated.ts # Auto-generated types
│ └── locales/ # i18n translations
hasura/
├── metadata/ # GraphQL schema, permissions
├── migrations/ # Database migrations
└── seeds/ # Test data
tests/
└── e2e/ # Playwright tests
- Kanban Board: Drag-and-drop task management
- Rich Tasks: Priority levels, due dates, markdown descriptions
- File Attachments: Upload files to tasks
- User Preferences: Dark mode, language selection
- Optimistic Updates: Instant UI feedback
- Production Logging: Comprehensive logging with database persistence
- Responsive Design: Mobile-first approach
- Type Safety: Full TypeScript + GraphQL codegen
- Sharing & Collaboration: Board invitations with role-based access
Stores follow a factory pattern in src/lib/stores/*.svelte.ts:
function createStore() {
const state = $state({
items: [],
loading: false,
error: null
});
async function loadItems() {
if (!browser) return; // Always check browser
state.loading = true;
try {
const data = await request(GET_ITEMS, {});
state.items = data.items || [];
} catch (error) {
state.error = error.message;
} finally {
state.loading = false;
}
}
return {
get items() { return state.items; },
get loading() { return state.loading; },
loadItems
};
}
export const store = createStore();Key Rules:
- Single
$stateobject for all reactive state - Always check
if (!browser)before browser APIs - Use
finallyfor loading state - Return
{ success, message, data? }from mutations - Use optimistic updates for instant UI feedback
- Add query/mutation to
src/lib/graphql/documents.ts - Run
npm run generateto generate types - Import types from
src/lib/graphql/generated.ts - Use
request()fromsrc/lib/graphql/client.ts
import { request } from '$lib/graphql/client';
import { GET_BOARDS } from '$lib/graphql/documents';
import type { GetBoardsQuery } from '$lib/graphql/generated';
const data: GetBoardsQuery = await request(GET_BOARDS, { user_id });# Open Hasura Console
cd hasura
hasura console
# Console features:
# - Data tab: Browse tables, run SQL
# - API tab: Test GraphQL queries
# - Events tab: Check triggersimport { loggingStore } from '$lib/stores/logging.svelte';
// Production logs (auto-saved to DB)
loggingStore.error('Component', 'Error msg', { error });
loggingStore.warn('Component', 'Warning', { context });
loggingStore.info('Component', 'Info', { data });
// Dev only (not persisted)
loggingStore.debug('Component', 'Debug', { data });View logs at: /[lang]/logs
# Development
npm run dev # Start dev server
npm run check # Type checking
npm test # Run tests
npm run generate # Generate GraphQL types
# Backend (from hasura/ directory)
hasura console # Open Hasura Console
hasura metadata apply # Apply metadata changes
hasura migrate apply --all-databases
hasura migrate create "migration_name" --from-server
# MCP
claude mcp list # List configured servers
claude mcp add # Add new server
claude mcp remove # Remove server
# Clean install
npm run cu # Unix-like systems
npm run cw # WindowsWhen NODE_ENV=development:
- Email:
test@test.com - Access:
/auth/signin - Delete in production!
# All tests
npm test
# E2E only
npm run test:e2e
# Unit/Component only
npm run test:unit
# With UI
npm run test:e2e -- --uiSEO-friendly URLs with auto-generated aliases:
- Boards:
/[lang]/[username]/[boardAlias] - Todos:
/[lang]/[username]/[boardAlias]/[todoAlias]
Examples:
/en/john-w/work-projects/en/sarah/personal-tasks/shopping
Aliases are auto-generated by PostgreSQL functions:
- Lowercase, hyphenated format
- Duplicate handling with numbers (
my-board,my-board-2) - Boards: Globally unique
- Todos: User-scoped unique
Planned: Custom usernames, shareable URLs without /[lang]
- User sends invitation → Creates
board_invitationsrow (status='pending') - Invitee logs in → Bell icon shows notification count
- Invitee clicks bell → Views pending invitations
- Invitee accepts → Creates
board_membersrow, updates status - Board appears in BoardSwitcher with "Shared" badge
npm run build
npm run preview- Auth.js: Authentication with JWT tokens (supports static adapter for mobile)
- nodemailer: Email sending (production: use paid service API)
- @neodrag/svelte: Drag-and-drop for Kanban
- shadcn-svelte: Accessible UI components (
npx shadcn-svelte add <component>) - lucide-svelte: Icon library
- svelte-tiptap: Rich markdown editor
- graphql-request: GraphQL client for Hasura
- Zod: Form validation
- sveltekit-i18n: Lightweight i18n (zero dependencies)
npm run check # Must pass
npm test # Must pass-
Use MCP tools for verification:
- Playwright for browser testing
- Sequential Thinking for complex planning
- Hasura Console for database verification
-
Follow store patterns:
- Factory pattern with
$state - Browser guards on all actions
- Optimistic updates for mutations
- Factory pattern with
-
Write tests:
- Unit tests for stores
- Component tests for UI
- E2E tests for workflows
-
Document changes:
- Update task files in
todo/folder - Document MCP verification performed
- Note test coverage
- Update task files in
If you encounter dependency conflicts:
npm install --maxsockets=1Check .env and hasura/.env files have correct credentials.
# Check status
claude mcp list
# Reconnect
claude mcp remove <server-name>
claude mcp add <server-name> -- <command>[Your License Here]
For issues or questions, please open an issue on GitHub.