a a vibe-coded abomination experiment of a fragrance review platform built on the atmosphere.
drydown.social
Existing Code Reference#
Related Documents:
- Architecture Overview - System design
- CLAUDE.md (project root) - Project overview
Current Codebase (🟢 Implemented)#
Authentication Module#
File: /src/auth.ts
Key Functions:
getClient()- Returns singleton BrowserOAuthClient instanceinitAuth()- Initializes OAuth and checks for existing sessionslogin(handle)- Initiates OAuth sign-in flow with Bluesky handle
OAuth Configuration:
client_id: Special format using localhost with encoded redirect_uriredirect_uris:['http://127.0.0.1:5173']handleResolver:'https://bsky.social'- CRITICAL: Must run on
127.0.0.1:5173(notlocalhost)
Example Usage:
// Initialize on app mount
useEffect(() => {
initAuth().then(session => {
if (session) setSession(session)
})
}, [])
// Login
const handleLogin = async (handle: string) => {
await login(handle) // Redirects to Bluesky OAuth
}
App Component#
File: /src/app.tsx
Responsibilities:
- Session state management (
session: OAuthSession | null) - Loading state during auth initialization
- Conditional rendering: LoginForm vs authenticated UI
- Sign out action
State:
const [session, setSession] = useState<OAuthSession | null>(null)
const [isInitializing, setIsInitializing] = useState(true)
Flow:
- App mounts → call
initAuth() - If session exists → show authenticated UI
- If no session → show LoginForm
LoginForm Component#
File: /src/components/LoginForm.tsx
Features:
- Text input for Bluesky handle (placeholder: "alice.bsky.social")
- Loading state during OAuth redirect
- Error message display
- Form submission handling
Example:
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="alice.bsky.social"
value={handle}
onChange={(e) => setHandle(e.target.value)}
/>
<button type="submit" disabled={loading}>
{loading ? 'Signing in...' : 'Sign In'}
</button>
{error && <div class="error">{error}</div>}
</form>
Development Server Configuration#
File: /vite.config.ts
Key Settings:
- Server host:
127.0.0.1(NOTlocalhost) - Server port:
5173 - This is REQUIRED for OAuth to work
export default defineConfig({
plugins: [preact()],
server: {
host: '127.0.0.1',
port: 5173
}
})
Known Limitations#
Logout Implementation (/src/app.tsx):
- Currently only clears UI state (
setSession(null)) - Does NOT revoke OAuth tokens
- Does NOT clear browser storage
- SDK limitation:
BrowserOAuthClientdoesn't expose token revocation
Future Improvement: Investigate SDK updates for proper logout
Project Structure#
/src
├── main.tsx # App entry point
├── app.tsx # Main App component (session mgmt)
├── auth.ts # OAuth client singleton
├── index.css # Global styles
├── app.css # App-specific styles
└── components/
└── LoginForm.tsx # Login form component
/public
├── vite.svg # Vite logo
└── client-metadata.json # OAuth metadata (served statically)
index.html # HTML entry point
vite.config.ts # Vite config (127.0.0.1:5173)
CLAUDE.md # Project documentation
Related Documents:
- Architecture Overview - Where new code will fit
- Implementation Roadmap - What to build next
- CLAUDE.md - Original project overview