···11-# Contributing to ATlast
22-33-Thank you for your interest in contributing! This guide will help you get started with local development.
44-55-## Two Development Modes
66-77-We support two development modes:
88-99-🎨 **Mock Mode** (No backend required)
1010-**Best for:** Frontend development, UI/UX work, design changes
1111-1212-🔧 **Full Mode** (Complete backend)
1313-**Best for:** Backend development, API work, OAuth testing, database changes
1414-1515-**Requirements:**
1616-- PostgreSQL database (local or Neon)
1717-- OAuth keys
1818-- Environment configuration
1919-2020----
2121-2222-## Mock Mode Starting Guide
2323-2424-Perfect for frontend contributors who want to jump in quickly!
2525-2626-1. Clone and Install
2727-```bash
2828-git clone <repo-url>
2929-cd atlast
3030-pnpm install
3131-```
3232-3333-2. Create .env.local
3434-```bash
3535-# .env.mock
3636-VITE_LOCAL_MOCK=true
3737-VITE_ENABLE_OAUTH=false
3838-VITE_ENABLE_DATABASE=false
3939-```
4040-4141-3. Start Development
4242-```bash
4343-pnpm run dev:mock
4444-```
4545-4646-4. Open Your Browser
4747-Go to `http://localhost:5173`
4848-4949-5. "Login" with Mock User
5050-Enter any handle - it will create a mock session.
5151-5252-6. Upload Test Data
5353-Upload your TikTok or Instagram data file. The mock API will generate fake matches for testing the UI.
5454-5555----
5656-5757-## Full Mode Starting Guide
5858-5959-For contributors working on backend features, OAuth, or database operations.
6060-6161-### Prerequisites
6262-6363-- Node.js 18+
6464-- pnpm (install with `npm install -g pnpm`)
6565-- PostgreSQL (or Neon account)
6666-- OpenSSL (for key generation)
6767-6868-1. Clone and Install
6969-```bash
7070-git clone <repo-url>
7171-cd atlast
7272-pnpm install
7373-```
7474-7575-2. Database Setup
7676-7777- **Option A: Neon (Recommended)**
7878- 1. Create account at https://neon.tech
7979- 2. Create project "atlast-dev"
8080- 3. Copy connection string
8181-8282- **Option B: Local PostgreSQL**
8383- ```bash
8484- # macOS
8585- brew install postgresql@15
8686- brew services start postgresql@15
8787- createdb atlast_dev
8888-8989- # Ubuntu
9090- sudo apt install postgresql
9191- sudo systemctl start postgresql
9292- sudo -u postgres createdb atlast_dev
9393- ```
9494-9595-3. Generate OAuth Keys
9696- ```bash
9797- # Generate private key
9898- openssl ecparam -name prime256v1 -genkey -noout -out private-key.pem
9999-100100- # Extract public key
101101- openssl ec -in private-key.pem -pubout -out public-key.pem
102102-103103- # View private key (copy for .env)
104104- cat private-key.pem
105105- ```
106106-107107-4. Extract Public Key JWK
108108- ```bash
109109- node -e "
110110- const fs = require('fs');
111111- const jose = require('jose');
112112- const pem = fs.readFileSync('public-key.pem', 'utf8');
113113- jose.importSPKI(pem, 'ES256').then(key => {
114114- return jose.exportJWK(key);
115115- }).then(jwk => {
116116- console.log(JSON.stringify(jwk, null, 2));
117117- });
118118- "
119119- ```
120120-121121-5. Update netlify/functions/jwks.ts
122122-123123- Replace `PUBLIC_JWK` with the output from step 4.
124124-125125-6. Create .env
126126-127127- ```bash
128128- VITE_LOCAL_MOCK=false
129129- VITE_API_BASE=/.netlify/functions
130130-131131- # Database (choose one)
132132- NETLIFY_DATABASE_URL=postgresql://user:pass@host/db # Neon
133133- # NETLIFY_DATABASE_URL=postgresql://localhost/atlast_dev # Local
134134-135135- # OAuth (paste your private key)
136136- OAUTH_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nYOUR_KEY_HERE\n-----END PRIVATE KEY-----"
137137-138138- # Local URLs (MUST use 127.0.0.1 for OAuth)
139139- URL=http://127.0.0.1:8888
140140- DEPLOY_URL=http://127.0.0.1:8888
141141- DEPLOY_PRIME_URL=http://127.0.0.1:8888
142142- CONTEXT=dev
143143- ```
144144-145145-7. Initialize Database
146146- ```bash
147147- pnpm run init-db
148148- ```
149149-150150-8. Start Development Server
151151- ```bash
152152- npx netlify-cli dev --filter @atlast/web
153153- # Or use the alias:
154154- pnpm run dev
155155- ```
156156-157157-9. Test OAuth
158158-159159- 1. Open `http://127.0.0.1:8888` (NOT localhost)
160160- 2. Enter your real Bluesky handle
161161- 3. Authorize the app
162162- 4. You should be redirected back and logged in
163163-164164----
165165-166166-## Project Structure
167167-168168-**Monorepo using pnpm workspaces:**
169169-170170-```
171171-atlast/
172172-├── packages/
173173-│ ├── web/ # Frontend React app
174174-│ │ ├── src/
175175-│ │ │ ├── assets/ # Logo
176176-│ │ │ ├── components/ # UI components (React)
177177-│ │ │ ├── pages/ # Page components
178178-│ │ │ ├── hooks/ # Custom hooks
179179-│ │ │ ├── lib/
180180-│ │ │ │ ├── api/ # API client (real + mock)
181181-│ │ │ │ ├── parsers/ # File parsing logic
182182-│ │ │ │ └── config.ts # Environment config
183183-│ │ │ └── types/ # TypeScript types
184184-│ │ └── package.json
185185-│ ├── functions/ # Netlify serverless functions
186186-│ │ ├── src/
187187-│ │ │ ├── core/ # Middleware, types, config
188188-│ │ │ ├── infrastructure/ # Database, OAuth, cache
189189-│ │ │ ├── services/ # Business logic
190190-│ │ │ ├── repositories/ # Data access layer
191191-│ │ │ └── utils/ # Shared utilities
192192-│ │ └── package.json
193193-│ ├── extension/ # Browser extension
194194-│ │ ├── src/
195195-│ │ │ ├── content/ # Content scripts, scrapers
196196-│ │ │ ├── popup/ # Extension popup UI
197197-│ │ │ ├── background/ # Service worker
198198-│ │ │ └── lib/ # Extension utilities
199199-│ │ └── package.json
200200-│ └── shared/ # Shared types (future)
201201-├── pnpm-workspace.yaml
202202-└── netlify.toml
203203-```
204204-205205-### UI Color System
206206-207207-| **Element** | **Light Mode** | **Dark Mode** | **Notes** |
208208-|:---:|:---:|:---:|:---:|
209209-| Text Primary | purple-950 | cyan-50 | Headings, labels |
210210-| Text Secondary | purple-750 | cyan-250 | Body text, descriptions |
211211-| Text Tertiary | purple-600 | cyan-400 | Metadata, hints, icons |
212212-| Borders (Rest) | cyan-500/30 | purple-500/30 | Cards, inputs default |
213213-| Borders (Hover) | cyan-400 | purple-400 | Interactive hover |
214214-| Borders (Active/Selected) | cyan-500 | purple-500 | Active tabs, selected items |
215215-| Backgrounds (Primary) | white | slate-900 | Modal/card base |
216216-| Backgrounds (Secondary) | purple-50 | slate-900 (nested sections) | Nested cards, sections |
217217-| Backgrounds (Selected) | cyan-50 | purple-950/30 | Selected platform cards |
218218-| Buttons Primary | orange-600 | orange-600 | CTAs |
219219-| Buttons Primary Hover | orange-500 | orange-500 | CTA hover |
220220-| Buttons Secondary | slate-600 | slate-700 | Cancel, secondary actions |
221221-| Buttons Secondary Hover | slate-700 | slate-600 | Secondary hover |
222222-| Interactive Selected | bg-cyan-50 border-cyan-500 | bg-purple-950/30 border-purple-500 | Platform selection cards |
223223-| Accent/Badge | orange-500 | orange-500 (or amber-500) | Match counts, checkmarks, progress |
224224-| Progress Complete | orange-500 | orange-500 | Completed progress bars |
225225-| Progress Incomplete | cyan-500/30 | purple-500/30 | Incomplete progress bars |
226226-| Success/Green | green-100/800 | green-900/300 | Followed status |
227227-| Error/Red | red-600 | red-400 | Logout, errors |
228228-229229-### UI Color System: Patterns
230230-**Disabled States**:
231231-- Light: Reduce opacity to 50%, use purple-500/50
232232-- Dark: Reduce opacity to 50%, use cyan-500/50
233233-234234-**Success/Match indicators**:
235235-Both modes: amber-* or orange-* backgrounds with accessible text contrast
236236-237237-**Tab Navigation**:
238238-- Inactive: Use text secondary colors
239239-- Active border: orange-500 (light), amber-500 (dark)
240240-- Active text: orange-650 (light), amber-400 (dark)
241241-242242-**Gradient Banners**:
243243-- Both modes: from-amber-* via-orange-* to-pink-* (keep dramatic, adjust shades for mode)
244244-245245----
246246-247247-## Task Workflows
248248-249249-### Adding a New Social Platform Parser
250250-251251-1. Add parsing rules to `packages/web/src/lib/parsers/platformDefinitions.ts`
252252-2. Follow existing patterns (TikTok, Instagram)
253253-3. Test with real data export file
254254-4. Update platform selection UI if needed
255255-256256-### Adding a New API Endpoint
257257-258258-1. Create `packages/functions/src/your-endpoint.ts`
259259-2. Add authentication check using `withAuthErrorHandling()` middleware
260260-3. Update `packages/web/src/lib/api/adapters/RealApiAdapter.ts`
261261-4. Update `packages/web/src/lib/api/adapters/MockApiAdapter.ts`
262262-5. Use in components via `apiClient.yourMethod()`
263263-264264-### Working with the Extension
265265-266266-```bash
267267-cd packages/extension
268268-pnpm install
269269-pnpm run build # Build for Chrome
270270-pnpm run build:prod # Build for production
271271-272272-# Load in Chrome:
273273-# 1. Go to chrome://extensions
274274-# 2. Enable Developer mode
275275-# 3. Click "Load unpacked"
276276-# 4. Select packages/extension/dist/chrome/
277277-```
278278-279279-### Styling Changes
280280-281281-- Use Tailwind utility classes
282282-- Follow dark mode pattern: `class="bg-white dark:bg-gray-800"`
283283-- Test in both light and dark modes
284284-- Mobile-first responsive design
285285-- Check accessibility (if implemented) is retained
286286-287287----
288288-289289-## Submitting Changes
290290-291291-### Before Submitting
292292-293293-- [ ] Test in mock mode: `pnpm run dev:mock`
294294-- [ ] Test in full mode (if backend changes): `npx netlify-cli dev --filter @atlast/web`
295295-- [ ] Check both light and dark themes
296296-- [ ] Test mobile responsiveness
297297-- [ ] No console errors
298298-- [ ] Code follows existing patterns
299299-- [ ] Run `pnpm run build` successfully
300300-301301-### Pull Request Process
302302-303303-1. Fork the repository
304304-2. Create a feature branch: `git checkout -b feature/your-feature`
305305-3. Make your changes
306306-4. Commit with clear messages
307307-5. Push to your fork
308308-6. Open a Pull Request
309309-310310-### PR Description Should Include
311311-312312-- What changes were made
313313-- Why these changes are needed
314314-- Screenshots (for UI changes)
315315-- Testing steps
316316-- Related issues
317317-318318----
319319-320320-## Resources
321321-322322-- [AT Protocol Docs](https://atproto.com)
323323-- [Bluesky API](https://docs.bsky.app)
324324-- [React Documentation](https://react.dev)
325325-- [Tailwind CSS](https://tailwindcss.com)
326326-- [Netlify Functions](https://docs.netlify.com/functions/overview)
327327-328328----
329329-330330-Thank you for contributing to ATlast!
+1-3
README.md
···11# ATlast
22ATlast — you'll never need to find your favorites on another platform again. This tool helps you find users you followed on other social platforms (TikTok, Instagram, Twitter/X, and more) within the ATmosphere, so you can keep in touch with them on Bluesky, Skylight, or whatever @pp you prefer!
3344-### Development
55-66-Check out [CONTRIBUTING.md](https://tangled.org/@byarielm.fyi/atlast/blob/master/CONTRIBUTING.md)44+## Coming Soon