{ "meta": { "phaseId": "PHASE_F0", "name": "Project Foundation", "version": "1.0.0", "created": "2026-01-30", "lastUpdated": "2026-01-30", "totalTasks": 8, "completedTasks": 8, "status": "completed" }, "tasks": [ { "id": "F0-001", "name": "Initialize Vite project", "description": "Create Vue 3 + TypeScript project with Vite", "category": "setup", "priority": 1, "completed": true, "tested": true, "dependencies": [], "files": [ {"path": "package.json", "status": "create"}, {"path": "vite.config.ts", "status": "create"}, {"path": "tsconfig.json", "status": "create"} ], "details": [ "npm create vite@latest . -- --template vue-ts", "Configure path aliases (@/ for src/)", "Set up TypeScript strict mode" ], "notes": "Completed in initial scaffold commit b9b803d" }, { "id": "F0-002", "name": "Install and configure Tailwind", "description": "Set up Tailwind CSS with custom theme", "category": "styling", "priority": 2, "completed": true, "tested": true, "dependencies": ["F0-001"], "files": [ {"path": "tailwind.config.js", "status": "create"}, {"path": "src/assets/main.css", "status": "create"} ], "details": [ "Install tailwindcss, postcss, autoprefixer", "Configure content paths", "Add Mantimon color palette (Pokemon-inspired)" ], "notes": "Completed in initial scaffold - using Tailwind v4 with @tailwindcss/postcss" }, { "id": "F0-003", "name": "Set up Vue Router", "description": "Configure routing with guards and lazy loading", "category": "setup", "priority": 3, "completed": true, "tested": true, "dependencies": ["F0-001"], "files": [ {"path": "src/router/index.ts", "status": "modify"}, {"path": "src/router/guards.ts", "status": "create"} ], "details": [ "Define route structure per sitePlan", "Create auth guard (requireAuth, requireGuest)", "Create starter guard (redirect if no starter deck)", "Configure lazy loading for heavy routes", "Extract guards to separate file" ], "notes": "Partial - router/index.ts exists with basic routes and inline guard. Needs guards.ts extraction and starter deck guard." }, { "id": "F0-004", "name": "Set up Pinia stores", "description": "Create store structure with persistence", "category": "stores", "priority": 4, "completed": true, "tested": true, "dependencies": ["F0-001"], "files": [ {"path": "src/stores/auth.ts", "status": "modify"}, {"path": "src/stores/user.ts", "status": "create"}, {"path": "src/stores/ui.ts", "status": "create"} ], "details": [ "Install pinia and pinia-plugin-persistedstate (done)", "Update auth store for OAuth flow (not username/password)", "Create user store skeleton (display_name, avatar, linked accounts)", "Create UI store (loading states, toasts, modals)" ], "notes": "Partial - auth.ts exists but uses username/password pattern instead of OAuth. Needs user.ts and ui.ts." }, { "id": "F0-005", "name": "Create API client", "description": "HTTP client with auth token injection and refresh", "category": "api", "priority": 5, "completed": true, "tested": true, "dependencies": ["F0-001", "F0-004"], "files": [ {"path": "src/api/client.ts", "status": "create"}, {"path": "src/api/types.ts", "status": "create"} ], "details": [ "Create fetch wrapper with base URL from config", "Inject Authorization header from auth store", "Handle 401 responses with automatic token refresh", "Type API responses (ApiError, ApiResponse)", "Add request/response interceptor pattern" ], "notes": "Not started. Critical for all backend communication." }, { "id": "F0-006", "name": "Create Socket.IO client", "description": "WebSocket connection manager", "category": "api", "priority": 6, "completed": true, "tested": true, "dependencies": ["F0-001", "F0-004"], "files": [ {"path": "src/socket/client.ts", "status": "create"}, {"path": "src/socket/types.ts", "status": "create"} ], "details": [ "Install socket.io-client (done)", "Create connection manager singleton", "Configure auth token in handshake", "Set up reconnection with exponential backoff", "Create typed event emitters for game namespace" ], "notes": "Not started. socket.io-client is installed." }, { "id": "F0-007", "name": "Create app shell", "description": "Basic layout with navigation", "category": "components", "priority": 7, "completed": true, "tested": true, "dependencies": ["F0-001", "F0-002", "F0-003"], "files": [ {"path": "src/App.vue", "status": "modify"}, {"path": "src/layouts/DefaultLayout.vue", "status": "create"}, {"path": "src/layouts/MinimalLayout.vue", "status": "create"}, {"path": "src/layouts/GameLayout.vue", "status": "create"}, {"path": "src/components/NavSidebar.vue", "status": "create"}, {"path": "src/components/NavBottomTabs.vue", "status": "create"}, {"path": "src/components/ui/LoadingOverlay.vue", "status": "create"}, {"path": "src/components/ui/ToastContainer.vue", "status": "create"}, {"path": "src/types/vue-router.d.ts", "status": "create"} ], "details": [ "Create DefaultLayout with sidebar (desktop) / bottom tabs (mobile)", "Create MinimalLayout for login/auth pages (centered, no nav)", "Create GameLayout for match page (full viewport, no nav)", "Responsive nav: NavSidebar for md+, NavBottomTabs for mobile", "Loading overlay component tied to UI store", "Toast notification container tied to UI store" ], "notes": "Completed - App.vue uses dynamic layout switching based on route meta. All layouts and navigation components created with tests." }, { "id": "F0-008", "name": "Environment configuration", "description": "Configure environment variables", "category": "setup", "priority": 8, "completed": true, "tested": true, "dependencies": ["F0-001"], "files": [ {"path": ".env.development", "status": "create"}, {"path": ".env.production", "status": "create"}, {"path": "src/config.ts", "status": "create"} ], "details": [ "Create .env.development with local API URLs", "Create .env.production with production API URLs", "Create type-safe config.ts that reads VITE_* vars", "Define: VITE_API_BASE_URL, VITE_WS_URL, VITE_OAUTH_REDIRECT_URI" ], "notes": "Not started. Needed before API client can work properly." } ] }