Monorepo for Aesthetic.Computer
aesthetic.computer
1# Moods ATProto Integration - Architecture Diagram
2
3```
4┌─────────────────────────────────────────────────────────────────────┐
5│ Aesthetic Computer User │
6│ (via prompt/api) │
7└───────────────────────────┬─────────────────────────────────────────┘
8 │
9 ↓
10┌─────────────────────────────────────────────────────────────────────┐
11│ POST /api/mood { mood: "happy!" } │
12│ (mood.mjs Netlify Function) │
13└───────────────────────────┬─────────────────────────────────────────┘
14 │
15 ┌───────────┴───────────┐
16 ↓ ↓
17┌───────────────────────────┐ ┌─────────────────────────┐
18│ MongoDB (PRIMARY) │ │ ATProto PDS (SECONDARY) │
19│ aesthetic.moods │ │ at.aesthetic.computer │
20│ │ │ │
21│ { │ │ { │
22│ user: "auth0|123", │ │ $type: "computer. │
23│ mood: "happy!", │ │ aesthetic.mood", │
24│ when: Date, │ │ text: "happy!", │
25│ atproto: { ←─────┼──┼── createdAt: ISO, │
26│ uri: "at://...", ←────┼──┼── mongoId: "abc" │
27│ cid: "bafy...", │ │ } │
28│ synced: true │ │ │
29│ } │ │ URI: at://did:plc:abc/ │
30│ } │ │ computer.aesthetic. │
31│ │ │ mood/3k... │
32└────────────┬───────────────┘ └──────────┬──────────────┘
33 │ │
34 │ ┌──────────────────────────┘
35 │ │
36 ↓ ↓
37┌─────────────────────────────────────────────────────────────────────┐
38│ Read Operations (GET) │
39│ • /api/mood/all - List all moods (MongoDB primary) │
40│ • /api/mood/@handle - Get user's latest (MongoDB) │
41│ • ATProto firehose - Federated discovery (ATProto) │
42└─────────────────────────────────────────────────────────────────────┘
43
44
45═════════════════════════════════════════════════════════════════════
46
47 DELETION FLOW
48
49┌─────────────────────────────────────────────────────────────────────┐
50│ POST /api/delete-erase-and-forget-me │
51│ (delete-erase-and-forget-me.mjs Function) │
52└───────────────────────────┬─────────────────────────────────────────┘
53 │
54 ┌───────────┴───────────┐
55 ↓ ↓
56┌───────────────────────────┐ ┌─────────────────────────┐
57│ MongoDB: DELETE moods │ │ ATProto PDS: DELETE │
58│ where user = sub │ │ all mood records │
59│ │ │ via repo.deleteRecord │
60│ ✓ All moods removed │ │ ✓ All moods removed │
61└────────────────────────────┘ └─────────────────────────┘
62
63
64═════════════════════════════════════════════════════════════════════
65
66 MIGRATION/BACKFILL FLOW
67
68┌─────────────────────────────────────────────────────────────────────┐
69│ node scripts/migrate-moods-to-atproto.mjs --execute │
70└───────────────────────────┬─────────────────────────────────────────┘
71 │
72 ↓
73 ┌────────────────┐
74 │ For each user │
75 │ with ATProto │
76 └────────┬───────┘
77 │
78 ↓
79 ┌─────────────────────────┐
80 │ Find moods without │
81 │ atproto.uri field │
82 └───────────┬─────────────┘
83 │
84 ↓
85 ┌───────────────────────────┐
86 │ For each mood: │
87 │ 1. Create ATProto record │
88 │ 2. Get URI + CID │
89 │ 3. Update MongoDB with │
90 │ atproto.uri │
91 │ 4. Wait 100ms (rate │
92 │ limit) │
93 └───────────┬───────────────┘
94 │
95 ↓
96 ┌───────────────────────────┐
97 │ Report: │
98 │ • Migrated: N moods │
99 │ • Failed: M moods │
100 │ • Total: X moods │
101 └───────────────────────────┘
102
103
104═════════════════════════════════════════════════════════════════════
105
106 AUDIT/VERIFICATION FLOW
107
108┌─────────────────────────────────────────────────────────────────────┐
109│ node scripts/audit-mood-atproto-sync.mjs @handle │
110└───────────────────────────┬─────────────────────────────────────────┘
111 │
112 ┌───────────┴───────────┐
113 ↓ ↓
114┌───────────────────────────┐ ┌─────────────────────────┐
115│ MongoDB Query: │ │ ATProto PDS Query: │
116│ • Total moods │ │ • listRecords() │
117│ • Moods with atproto.uri │ │ • Count records │
118│ • Moods missing ATProto │ │ • Sample records │
119└────────────┬───────────────┘ └──────────┬──────────────┘
120 │ │
121 │ ┌──────────────────────────┘
122 │ │
123 ↓ ↓
124┌─────────────────────────────────────────────────────────────────────┐
125│ Compare & Report │
126│ ✓ MongoDB: 150 moods │
127│ ✓ ATProto: 150 records │
128│ ✓ Sync Rate: 100% │
129│ ✓ All checks passed! │
130└─────────────────────────────────────────────────────────────────────┘
131
132
133═════════════════════════════════════════════════════════════════════
134
135 DATA FLOW SUMMARY
136
137 User Action → MongoDB (PRIMARY) → ATProto (SECONDARY)
138 ↓ ↓
139 Source of truth Federated copy
140 Fast queries ATProto network
141 Existing data New discovery
142 Soft deletes Permanent records*
143
144 * ATProto records can be deleted, but deletion is explicit via API
145
146
147═════════════════════════════════════════════════════════════════════
148
149 LEXICON DEFINITION
150
151 computer.aesthetic.mood {
152 text: string (max 280 chars) ← The mood content
153 createdAt: datetime ← Timestamp
154 intensity: int (1-10, optional) ← Future feature
155 context: string (optional) ← Additional notes
156 isPrivate: boolean (default false) ← Federation control
157 mongoId: string ← Back-reference
158 }
159
160 Collection namespace: computer.aesthetic.mood
161 Record key: tid (timestamp-based ID)
162 URI format: at://did:plc:abc.../computer.aesthetic.mood/3k...
163
164
165═════════════════════════════════════════════════════════════════════
166
167 IMPLEMENTATION PHASES
168
169 Week 1: ┌─────────────────────┐
170 │ 1. Deploy Lexicon │
171 │ 2. Create Helpers │
172 │ 3. Test Dual-Write │
173 └─────────────────────┘
174
175 Week 2: ┌─────────────────────┐
176 │ 4. Delete Sync │
177 │ 5. Migration Script │
178 │ 6. Test Migration │
179 └─────────────────────┘
180
181 Week 3: ┌─────────────────────┐
182 │ 7. Backfill All │
183 │ 8. Audit & Verify │
184 │ 9. Monitoring │
185 └─────────────────────┘
186
187 Week 4: ┌─────────────────────┐
188 │ 10. Documentation │
189 │ 11. Production │
190 │ 12. Complete ✅ │
191 └─────────────────────┘
192```