# Implementation Plan: Google OAuth Authentication Screen **Branch**: `001-google-oauth-auth` | **Date**: 2026-01-29 | **Spec**: [spec.md](./spec.md) **Input**: Feature specification from `/specs/001-google-oauth-auth/spec.md` ## Summary Implement a Google OAuth 2.0 authentication screen that gates access to the ThumbPreview tool. Users must authenticate via Google before accessing protected routes (/tool). The implementation uses redirect-based OAuth flow with session persistence (7-day validity), preserving the user's originally requested destination after login. Backend handles OAuth callback and session management; frontend provides auth UI and route protection. ## Technical Context **Language/Version**: TypeScript 5.x (frontend + backend) **Primary Dependencies**: - Frontend: React 19.x, React Router 7.x, Zustand 5.x, @tanstack/react-query 5.x, shadcn/ui - Backend: NestJS 11.x, TypeORM 0.3.x, @nestjs/passport, passport-google-oauth20 **Storage**: PostgreSQL (users, sessions via TypeORM) **Testing**: Jest (backend), manual testing (frontend) **Target Platform**: Web (desktop + mobile browsers) **Project Type**: Web application (frontend + backend monorepo) **Performance Goals**: OAuth flow completion < 30 seconds, session validation < 100ms **Constraints**: Must work with existing Vite proxy setup, no .env in frontend **Scale/Scope**: Single user role, 7-day session validity with refresh ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* | Principle | Status | Notes | |-----------|--------|-------| | I. Tech Stack | ✅ PASS | Using React 19, NestJS 11, TypeORM, PostgreSQL per constitution | | II. Architecture | ✅ PASS | Following monorepo structure: frontend/src/, backend/src/modules/ | | III. Styling & UI | ✅ PASS | Will use shadcn/ui Button, Card components with Tailwind | | IV. Data Management | ✅ PASS | Zustand for auth state, React Query for user data, TypeORM for persistence | | V. Development Practices | ✅ PASS | TypeScript strict mode, class-validator DTOs, ESLint | **New Dependencies Required**: - `@nestjs/passport` + `passport` + `passport-google-oauth20` - OAuth authentication (NestJS official, MIT license) - `@types/passport-google-oauth20` - TypeScript types **Justification**: Passport.js is the de facto standard for Node.js authentication. @nestjs/passport provides official NestJS integration. These are well-maintained, MIT-licensed, and have minimal bundle impact (backend only). ## Project Structure ### Documentation (this feature) ```text specs/001-google-oauth-auth/ ├── plan.md # This file ├── research.md # Phase 0 output ├── data-model.md # Phase 1 output ├── quickstart.md # Phase 1 output ├── contracts/ # Phase 1 output │ └── auth-api.yaml # OpenAPI spec for auth endpoints └── tasks.md # Phase 2 output (/speckit.tasks command) ``` ### Source Code (repository root) ```text backend/ ├── src/ │ ├── modules/ │ │ ├── auth/ # NEW: Authentication module │ │ │ ├── auth.module.ts │ │ │ ├── auth.controller.ts │ │ │ ├── auth.service.ts │ │ │ ├── google.strategy.ts │ │ │ ├── jwt.strategy.ts │ │ │ ├── guards/ │ │ │ │ ├── jwt-auth.guard.ts │ │ │ │ └── google-auth.guard.ts │ │ │ └── dto/ │ │ │ └── auth-response.dto.ts │ │ ├── thumbnails/ # Existing │ │ └── youtube/ # Existing │ └── entities/ │ ├── user.entity.ts # NEW │ ├── thumbnail.entity.ts # Existing │ └── youtube-cache.entity.ts # Existing └── tests/ frontend/ ├── src/ │ ├── components/ │ │ ├── AuthGuard.tsx # NEW: Route protection wrapper │ │ └── UserMenu.tsx # NEW: User avatar + sign out │ ├── pages/ │ │ ├── LoginPage.tsx # NEW: Auth screen │ │ ├── AuthCallbackPage.tsx # NEW: OAuth callback handler │ │ ├── LandingPage.tsx # Existing (public) │ │ └── ToolPage.tsx # Existing (protected) │ ├── store/ │ │ └── authStore.ts # NEW: Auth state (Zustand) │ ├── api/ │ │ └── auth.ts # NEW: Auth API client │ └── hooks/ │ └── useAuth.ts # NEW: Auth hook └── tests/ ``` **Structure Decision**: Web application structure with frontend/backend separation per constitution. Auth module added to backend following NestJS module pattern. Frontend gets new pages for login flow and components for route protection. ## Complexity Tracking No constitution violations. All implementation follows established patterns. --- ## Post-Design Constitution Re-Check *Re-validated after Phase 1 design completion.* | Principle | Status | Validation | |-----------|--------|------------| | I. Tech Stack | ✅ PASS | Dependencies align: @nestjs/passport, passport-google-oauth20 (MIT, maintained) | | II. Architecture | ✅ PASS | Auth module follows NestJS pattern, frontend follows components/pages/store structure | | III. Styling & UI | ✅ PASS | LoginPage will use shadcn/ui Button, Card; Tailwind for layout | | IV. Data Management | ✅ PASS | User entity uses UUID PK, Zustand for auth state, TypeORM for persistence | | V. Development Practices | ✅ PASS | DTOs with class-validator, explicit TypeScript types, ESLint compliance | **Phase 1 Artifacts Generated**: - ✅ `research.md` - OAuth implementation patterns documented - ✅ `data-model.md` - User and RefreshToken entities defined - ✅ `contracts/auth-api.yaml` - OpenAPI spec for 5 auth endpoints - ✅ `quickstart.md` - Setup and testing guide - ✅ `CLAUDE.md` - Agent context updated with new technologies