Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
Markdown
User Pages Architecture Diagram #
Request Flow #
┌─────────────────────────────────────────────────────────────────┐
│ User's Browser │
│ │
│ URL: https://fifi.at.aesthetic.computer │
└─────────────────────────────────────────────────────────────────┘
│
│ HTTP GET /
▼
┌─────────────────────────────────────────────────────────────────┐
│ Caddy Reverse Proxy │
│ (at.aesthetic.computer) │
│ │
│ Config for *.at.aesthetic.computer: │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ GET / → Serve user-page.html (static) │ │
│ │ GET /xrpc/* → Proxy to PDS:3000 (API) │ │
│ │ GET /.well-known/* → Proxy to PDS:3000 (ATProto) │ │
│ └────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
│ Returns user-page.html
▼
┌─────────────────────────────────────────────────────────────────┐
│ user-page.html (Client-Side) │
│ │
│ JavaScript extracts handle from URL: │
│ "fifi.at.aesthetic.computer" → "fifi.at.aesthetic.computer" │
│ │
│ Then makes API calls... │
└─────────────────────────────────────────────────────────────────┘
│
│ Multiple XRPC API calls
▼
┌─────────────────────────────────────────────────────────────────┐
│ ATProto PDS Server (Port 3000) │
│ │
│ XRPC Endpoints: │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ /xrpc/com.atproto.identity.resolveHandle │ │
│ │ Input: handle (fifi.at.aesthetic.computer) │ │
│ │ Output: { did: "did:plc:..." } │ │
│ │ │ │
│ │ /xrpc/com.atproto.repo.listRecords │ │
│ │ Input: repo (DID), collection │ │
│ │ Output: { records: [...], cursor: "..." } │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ Collections queried: │
│ • computer.aesthetic.painting │
│ • computer.aesthetic.mood │
│ • computer.aesthetic.piece │
│ • computer.aesthetic.kidlisp │
└─────────────────────────────────────────────────────────────────┘
│
│ Returns JSON data
▼
┌─────────────────────────────────────────────────────────────────┐
│ user-page.html (Rendering) │
│ │
│ Displays: │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Header: │ │
│ │ • Handle: @fifi.at.aesthetic.computer │ │
│ │ • DID: did:plc:... │ │
│ │ • Stats: 5 paintings, 12 moods, etc. │ │
│ │ │ │
│ │ Tabs: │ │
│ │ [All] [Paintings] [Moods] [Pieces] [KidLisp] │ │
│ │ │ │
│ │ Records Grid: │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ 🎨 Painting │ │ │
│ │ │ [Image thumbnail] │ │ │
│ │ │ Oct 20, 2025 • #abc123 │ │ │
│ │ │ View on pdsls.dev → │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ 💭 Mood │ │ │
│ │ │ "Feeling creative today!" │ │ │
│ │ │ Oct 19, 2025 │ │ │
│ │ │ View on pdsls.dev → │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Data Flow Sequence #
1. User visits https://fifi.at.aesthetic.computer
↓
2. Caddy serves /var/www/at.aesthetic.computer/user.html
↓
3. Browser loads user-page.html
↓
4. JavaScript extracts "fifi" from subdomain
↓
5. API Call #1: Resolve handle to DID
POST /xrpc/com.atproto.identity.resolveHandle
→ Returns: did:plc:xyz123...
↓
6. API Call #2: List paintings
GET /xrpc/com.atproto.repo.listRecords
?repo=did:plc:xyz123...&collection=computer.aesthetic.painting
→ Returns: { records: [...], cursor: null }
↓
7. API Call #3: List moods
GET /xrpc/com.atproto.repo.listRecords
?repo=did:plc:xyz123...&collection=computer.aesthetic.mood
→ Returns: { records: [...], cursor: null }
↓
8. API Call #4, #5: List pieces, kidlisp (parallel)
↓
9. Render all records in tabbed interface
↓
10. User can:
- Switch tabs to filter by type
- Click records to view on pdsls.dev
- See images loaded from blob storage
File Structure on Server #
/var/www/at.aesthetic.computer/
├── index.html ← Landing page (at.aesthetic.computer)
└── user.html ← User page (*.at.aesthetic.computer)
/pds/
└── Caddyfile ← Reverse proxy configuration
Key Benefits #
✅ Decentralized - No aesthetic.computer backend dependency
✅ Fast - Static file served from CDN
✅ Transparent - All data from public ATProto APIs
✅ Portable - Users own their data via ATProto
✅ Scalable - No server-side processing
Comparison with Main Landing Page #
| Feature | at.aesthetic.computer | [handle].at.aesthetic.computer |
|---|---|---|
| Purpose | Project overview | User-specific data |
| Content | All users' paintings/moods | Single user's records |
| Data Source | aesthetic.computer APIs | ATProto APIs only |
| Authentication | None | None (future: optional) |
| Caching | Static + API calls | Static + API calls |
Future: Authenticated Features #
User logs in (ATProto session)
↓
Verify ownership of handle
↓
Show admin controls:
• Delete records
• Edit metadata
• Privacy settings
• Export data
This will be implemented in Phase 1 of enhancements.
See: USER-PAGES.md for full documentation