Estimate: 15m · Depends on: 1.1.2, 1.1.3
Add Google OAuth as a peer sign-in method to the Better-Auth instance configured in 1.1.2. Wires the provider's config block, the OAuth callback handler (Better-Auth mounts it automatically once the provider is registered), and the auto-link semantics so that a Google sign-in with an email matching an existing password account links into the same User row. No UI work in this subtask — the "Continue with Google" button on the sign-in/sign-up pages lands in 1.1.5, which depends on this.
Why auto-link, not require-verification: Decided in Story-1.1 planning conversation (recorded in MOTIR.md). Same email → same user; both methods work afterward. Lowest-friction UX; the security trade-off (Google-account compromise → full account takeover) is acceptable for v1 because Google already verified the email and most users use Google with 2FA on. If a future Story needs require-verification semantics for compliance reasons, swap the accountLinking Better-Auth option there.
Why env-var-driven with no shipped defaults: Per the planner-as-consumer principle (MOTIR.md "Current state" + notes.html mistake #22), each Motir-planned project owns its own Google Cloud OAuth app. The starters ship GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET as required env vars with no defaults; the planner adds a "Set up Google Cloud OAuth credentials" Story in pre-plan for each project, parallel to the email-provider Story. In dev, missing creds make the Google button render but error visibly when clicked — no silent fallback.
What you'll do: Extend /lib/auth/index.ts (from 1.1.2) to register the Google social provider with clientId / clientSecret read from env, and enable accountLinking with the trustedProviders: ["google"] option so matching emails auto-link. Wire the OAuth callback to use findOrCreateOAuthUser from /lib/users/repo.ts (from 1.1.3). Document GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET in .env.example with a comment explaining where to obtain them (Google Cloud Console → APIs & Services → Credentials → OAuth 2.0 Client ID, web application, authorized redirect URI {BETTER_AUTH_URL}/api/auth/callback/google).
/lib/auth/index.ts; reads GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET from env.accountLinking.trustedProviders includes "google"; auto-link by matching email is enabled./app/api/auth/[...all]/route.ts (mounted by 1.1.2) handles Google's callback round-trip; on success the user is created or linked via findOrCreateOAuthUser from 1.1.3.passwordHash: null and emailVerifiedAt set to the OAuth callback time (Google has already verified the email).OAuthAccount row is created linking to the existing User; the existing passwordHash is unchanged; both sign-in methods work afterward..env.example documents GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET with a comment pointing to Google Cloud Console + the redirect URI shape..env, hitting /api/auth/sign-in/social?provider=google directly (no UI) redirects to Google's consent screen, then after consent redirects back, creates a session cookie, and the protected route renders.findOrCreateOAuthUser's auto-link branch (called above in 1.1.3's AC list — verify here that the OAuth callback actually invokes it correctly via a stubbed Google response)./lib/auth/index.ts — Better-Auth instance from 1.1.2 (to extend)/lib/users/repo.ts — user repository with findOrCreateOAuthUser from 1.1.3/prisma/schema.prisma — OAuthAccount model from 1.1.3.env.example — env-var pattern to extend