Docs/authentication#62
Conversation
|
Nice work on this 👏 The structure is solid: clear phases, env setup, troubleshooting, and acceptance criteria. That's how a real design doc is laid out, so the instincts are right. I read through it closely. One framing suggestion first, then the specific technical issues (each with a quick diagram). Suggestion: split this into two docsRight now the file mixes two jobs:
The problem is that several code snippets won't actually run against the current codebase (details below), so anyone following them literally hits errors, even though the design around them is fine. Mixing the two means a small code mistake undermines a doc that's otherwise useful. I'd suggest:
That way the design can merge now and be useful, while the implementation gets verified piece by piece instead of being asserted as done. Technical issues in the implementation snippetsThese matter for the TODO/implementation side. Even in a design doc, worth correcting so the intent is accurate. 1. Auth routes get wired twice, in two incompatible ways. flowchart TD
A["app.js<br/>mountAuthRoutes(app)"] --> R["/api/auth routes"]
B["routes/index.js<br/>app.use('/api/auth', makeAuthRouter())"] --> R
R --> D["Registered twice<br/>+ export shape mismatch"]
2. Frontend calls the wrong paths. flowchart LR
FE["apiClient<br/>GET /auth/github"] -->|missing /api| X["404 Not Found"]
BE["backend mount<br/>/api/auth/github"]
REF["runScan -> /api/scan ✅"]
3. Frontend and backend disagree on the auth model. sequenceDiagram
participant FE as Frontend
participant BE as Backend
Note over FE: sends Authorization: Bearer (from localStorage)
Note over BE: expects session cookie
FE->>BE: request (no cookie, no credentials:'include')
BE-->>FE: response (sets session cookie, no token in body)
Note over FE,BE: each side ignores what the other sends
4. classDiagram
class AuthService {
+getGitHubClient()
+getGoogleDriveClient()
}
class StorageService {
+getOrCreateStorage()
+saveScanResults()
}
StorageService ..> AuthService : calls this.getGitHubClient() but it lives here, not on this
5. The user loses its tokens after the first request. sequenceDiagram
participant FE as Frontend
participant BE as Backend
FE->>BE: login callback
Note over BE: req.user = full user (tokens, storage)
FE->>BE: next request (POST /api/scan)
Note over BE: deserializeUser -> req.user = { id } only
BE-->>FE: fails: req.user.storage is undefined
6. Backend imports a frontend ESM module. flowchart LR
subgraph BE["backend (CommonJS)"]
A["routes/auth.js<br/>require(...)"]
end
subgraph FE["frontend (ESM)"]
B["placeholders.js<br/>export const PROVIDERS"]
end
A -->|require an ESM file<br/>across layers| B
B --> X["throws + breaks layering<br/>(and PROVIDERS unused)"]
7. Two API calls aren't valid as written. 8. Minor: the One inconsistency to clean upThe acceptance criteria say "✅ No frontend changes required," but Phase 2 is entirely frontend changes (and references a How to verify all of this yourself (the fundamentals)First: writing the docs before the code was a genuinely good call. When you're doing something for the first time, laying out the plan in writing is how you find the gaps before they cost you hours of debugging. That instinct is worth keeping. And none of the findings above needed anything clever. Every one is just checking whether what's written is actually true. The doc says "call this method", "import from here", "the route is X"; each of those is a claim, and reviewing is nothing more than opening the real file and confirming the claim holds. A simple loop you can run on any PR:
The underlying rule: treat every method name, file path, route string, and import as a claim to be confirmed, not trusted. Bottom lineThe thinking is all here. It just needs the snippets lined up with how the codebase is actually wired. My main ask is splitting design from implementation so the good parts can land now. Happy to pair on any of the above. |
Documentation for the authentication feature of this project.