Initial commit
This commit is contained in:
75
.claude/settings.local.json
Normal file
75
.claude/settings.local.json
Normal file
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(npm create:*)",
|
||||
"Bash(npm install)",
|
||||
"Bash(npm install:*)",
|
||||
"Bash(npx tailwindcss:*)",
|
||||
"Bash(./node_modules/.bin/tailwindcss:*)",
|
||||
"Bash(npm ls:*)",
|
||||
"Bash(curl -s -X POST \"http://localhost:3000/api/firebase/v1/token?key=AIzaSyD9o9mzulN50-hqOwF6ww9pxUNUxwVOCXA\" -H \"Content-Type: application/json\" -d '{\"\"grantType\"\":\"\"refresh_token\"\",\"\"refreshToken\"\":\"\"AMf-vBxB7p1m84Jw8GNk1CsuEbgMInPt0lzOKXK81e-XiO13PUeA1VfkZ6gu29MN6izbLIWrBqeGaczU3DC5FY-vSePOoGAn3RZnjLWN2DzLmTiOiAH25UxTZPeE3d-g_8-JeBDgQptuP1xy1U0EGxM5msolSLEu8GBRnkxAtEhoIzVtyjCsaD1aBHdWqZiIPStLz-6YQj2j-pDoEVYr3aOBvNxnzv_vL4y91wFkVtMFaC0jOZZE39gbbSj5GH7JcHHiW-NJFcfD0BYKM9zfqs0SxPaYYuqTSQyS3lra1SVxn0XB-ZhcR-I\"\"}')",
|
||||
"Bash(TOKEN=\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjFjMzIxOTgzNGRhNTBlMjBmYWVhZWE3Yzg2Y2U3YjU1MzhmMTdiZTEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vZjItcHJvZC01MzQ3NSIsImF1ZCI6ImYyLXByb2QtNTM0NzUiLCJhdXRoX3RpbWUiOjE3NTQ1MDU5NTEsInVzZXJfaWQiOiJkVkRCalVRakF2WHBZMWl0aUF1N2txOTdEUHkyIiwic3ViIjoiZFZEQmpVUWpBdlhwWTFpdGlBdTdrcTk3RFB5MiIsImlhdCI6MTc2OTI1NzIxNSwiZXhwIjoxNzY5MjYwODE1LCJlbWFpbCI6InJ5NzRwMjV4MnZAcHJpdmF0ZXJlbGF5LmFwcGxlaWQuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImZpcmViYXNlIjp7ImlkZW50aXRpZXMiOnsiYXBwbGUuY29tIjpbIjAwMTc1MS45NTZkNjJkODA2YjY0ZTgzYjFhNTBmNjBkMDBhNDYyZi4wMTU3Il0sImVtYWlsIjpbInJ5NzRwMjV4MnZAcHJpdmF0ZXJlbGF5LmFwcGxlaWQuY29tIl19LCJzaWduX2luX3Byb3ZpZGVyIjoiYXBwbGUuY29tIn19.X6CSKNsEEoOOepMcSky4qkV2dnKmiZ8GI_9PkrWp0rAyGcD3HJFYJk3T5LmmP9lnyrAzIIRPeXQ0qHCN4ZLdzLNBu4gDdVDvlAKe0xX5DM2ee0goJAreS3Sy3SsEADsFLQvpaAT_aWkZj0bJ3nm_oAMQMu5VMqmuHyBPfxFhZNWErVmCahsZlIQnDJirI0r5k2wGPNZDdAzbaKESNFpU60EcxdWWGin7P0dUOADKftAdNbcr08Jtek17f0V3jma4N2F8lvS2IAW-2v-dDz1uOePCWHKeRH10TQQGqVR-vYoNU-ekHugpJ2tJ7qrME238R1IOuQRzLSJLMvwX9WuJ0A\")",
|
||||
"Bash(__NEW_LINE_c7bab749a7abcf34__ curl -s -X POST \"http://localhost:3000/api/graphql\" -H \"Content-Type: application/json\" -H \"Accept: */*\" -H \"Authorization: Bearer $TOKEN\" -H \"x-profile-id: profile#73b79341-5ff8-411c-806f-5b25cb834471\" -H \"x-device-os: ios\" -H \"x-app-version: 8.7.8\" -H \"x-os-version: 18.6.2\" -H \"x-transaction-id: test-123\" -H \"x-event-analytics-id: 53923e7d-39bb-42ac-99c6-99cdf6008d11\" -d '{\"\"query\"\":\"\"query { profile\\(profileId: \\\\\"\"profile#73b79341-5ff8-411c-806f-5b25cb834471\\\\\"\"\\) { id imaginaryName } }\"\"}')",
|
||||
"Bash(__NEW_LINE_f4d4c9f184cf811b__ curl -s -X POST \"http://localhost:3000/api/graphql\" -H \"Content-Type: application/json\" -H \"Accept: */*\" -H \"Authorization: Bearer $TOKEN\" -H \"x-profile-id: profile#73b79341-5ff8-411c-806f-5b25cb834471\" -H \"x-device-os: ios\" -H \"x-app-version: 8.7.8\" -H \"x-os-version: 18.6.2\" -H \"x-transaction-id: test-123\" -H \"x-event-analytics-id: 53923e7d-39bb-42ac-99c6-99cdf6008d11\" -d '{\"\"query\"\":\"\"query ProfileQuery\\($profileId: String!\\) { profile\\(id: $profileId\\) { id imaginaryName age gender } }\"\",\"\"variables\"\":{\"\"profileId\"\":\"\"profile#73b79341-5ff8-411c-806f-5b25cb834471\"\"}}')",
|
||||
"Bash(curl:*)",
|
||||
"Bash(node -e:*)",
|
||||
"Bash(npx tsc:*)",
|
||||
"Bash(unzip:*)",
|
||||
"Bash(python3:*)",
|
||||
"Bash(done)",
|
||||
"Skill(frontend-design)",
|
||||
"Bash(for f in request_*)",
|
||||
"Bash(do if grep -q \"WhoLikesMe\\\\|whoLikesMe\\\\|filteredWhoLikesMe\" \"$f\")",
|
||||
"Bash(then echo \"=== $f ===\")",
|
||||
"Bash(fi)",
|
||||
"Bash(do grep -l \"interactions\\\\|Interaction\\\\|whoLikes\\\\|whoPings\" \"$f\")",
|
||||
"Bash(source /tmp/feeld_creds.sh)",
|
||||
"Bash(docker restart:*)",
|
||||
"Bash(docker logs:*)",
|
||||
"Bash(cat:*)",
|
||||
"Bash(docker-compose down:*)",
|
||||
"Bash(docker-compose up:*)",
|
||||
"Bash(docker ps:*)",
|
||||
"Bash(docker exec feeld-web-nginx curl -s http://feeld-web-backend:3001/api/auth/login -X POST -H \"Content-Type: application/json\" -d '{\"\"username\"\":\"\"admin\"\",\"\"password\"\":\"\"feeld123\"\"}')",
|
||||
"Bash(docker exec:*)",
|
||||
"Bash(docker port:*)",
|
||||
"Bash(nc:*)",
|
||||
"Bash(docker-compose restart:*)",
|
||||
"Bash(lsof:*)",
|
||||
"Bash(docker network:*)",
|
||||
"Bash(docker-compose build:*)",
|
||||
"Bash(docker version:*)",
|
||||
"Bash(osascript:*)",
|
||||
"Bash(open:*)",
|
||||
"Bash(zip:*)",
|
||||
"Bash(for f in /Users/treyt/Desktop/code/Feeld/proxyman_extracted/request_*)",
|
||||
"Bash(do)",
|
||||
"Bash(if grep -l \"sendMessage\\\\|GetMessages\\\\|channel\\\\|chat.getstream\" \"$f\")",
|
||||
"Bash(then)",
|
||||
"Bash(echo:*)",
|
||||
"Bash(ls:*)",
|
||||
"Bash(grep:*)",
|
||||
"Bash(npm run build:*)",
|
||||
"Bash(timeout 15 npm run dev:*)",
|
||||
"Bash(docker-compose ps:*)",
|
||||
"Bash(docker-compose logs:*)",
|
||||
"Bash(for f in /Users/treyt/Desktop/code/Feeld/proxyman_chat/request_*)",
|
||||
"Bash(do echo \"=== $f ===\" cat \"$f\")",
|
||||
"WebSearch",
|
||||
"Bash(docker compose:*)",
|
||||
"Bash(docker compose build:*)",
|
||||
"Bash(ACCESS_TOKEN=\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjFjMzIxOTgzNGRhNTBlMjBmYWVhZWE3Yzg2Y2U3YjU1MzhmMTdiZTEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vZjItcHJvZC01MzQ3NSIsImF1ZCI6ImYyLXByb2QtNTM0NzUiLCJhdXRoX3RpbWUiOjE3NTQ1MDU5NTEsInVzZXJfaWQiOiJkVkRCalVRakF2WHBZMWl0aUF1N2txOTdEUHkyIiwic3ViIjoiZFZEQmpVUWpBdlhwWTFpdGlBdTdrcTk3RFB5MiIsImlhdCI6MTc2OTI3NTE3MCwiZXhwIjoxNzY5Mjc4NzcwLCJlbWFpbCI6InJ5NzRwMjV4MnZAcHJpdmF0ZXJlbGF5LmFwcGxlaWQuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImZpcmViYXNlIjp7ImlkZW50aXRpZXMiOnsiYXBwbGUuY29tIjpbIjAwMTc1MS45NTZkNjJkODA2YjY0ZTgzYjFhNTBmNjBkMDBhNDYyZi4wMTU3Il0sImVtYWlsIjpbInJ5NzRwMjV4MnZAcHJpdmF0ZXJlbGF5LmFwcGxlaWQuY29tIl19LCJzaWduX2luX3Byb3ZpZGVyIjoiYXBwbGUuY29tIn19.wSyOIOlzhrWsjYrOKyFJReAx8xANive5sbvUk2RChQ6rmnOxkgTUQABrd3YXzBiz2qvtS1yESp2bEy3XdvdkPjvKg4RTe8xWaYIIwvajFRgmoQG_bE6GRyrrKzeqshe72klNUhEPJDLGy4ERPRHaCVp27GyN2pyLC1uAqCal6NjMafcBlxGJXe263a6naDdeyM1Zl_GxRgFbdrPWJ6Ua335DDaNVvToM9z73USzSACADccX0xX20vUBz-7TWnjfYjBFXRdbauawF3V7PqfGwuROPc_F7Zb1bxcZPWP37Rgg2m_BzMPzcOarxHITRqUrK5accSaML-Rogkf6fg4ZoWA\")",
|
||||
"Bash(__NEW_LINE_f2a0275964ca9170__ curl -s -X POST 'https://core.api.fldcore.com/graphql' -H 'Content-Type: application/json' -H \"Authorization: Bearer $ACCESS_TOKEN\" -H 'x-profile-id: profile#73b79341-5ff8-411c-806f-5b25cb834471' -H 'x-device-os: ios' -H 'x-app-version: 8.7.8' -H 'x-os-version: 18.6.2' -H 'User-Agent: feeld-mobile' -d '{\"\"operationName\"\":\"\"ListSummaries\"\",\"\"variables\"\":{\"\"limit\"\":10},\"\"query\"\":\"\"query ListSummaries\\($limit: Int = 30, $cursor: String\\) { summaries: getChatSummariesForChatList\\(limit: $limit, cursor: $cursor\\) { nodes { id name type status streamChannelId } } }\"\"}')",
|
||||
"Bash(TOKEN=\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjFjMzIxOTgzNGRhNTBlMjBmYWVhZWE3Yzg2Y2U3YjU1MzhmMTdiZTEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vZjItcHJvZC01MzQ3NSIsImF1ZCI6ImYyLXByb2QtNTM0NzUiLCJhdXRoX3RpbWUiOjE3NTQ1MDU5NTEsInVzZXJfaWQiOiJkVkRCalVRakF2WHBZMWl0aUF1N2txOTdEUHkyIiwic3ViIjoiZFZEQmpVUWpBdlhwWTFpdGlBdTdrcTk3RFB5MiIsImlhdCI6MTc2OTI3NTI2MSwiZXhwIjoxNzY5Mjc4ODYxLCJlbWFpbCI6InJ5NzRwMjV4MnZAcHJpdmF0ZXJlbGF5LmFwcGxlaWQuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImZpcmViYXNlIjp7ImlkZW50aXRpZXMiOnsiYXBwbGUuY29tIjpbIjAwMTc1MS45NTZkNjJkODA2YjY0ZTgzYjFhNTBmNjBkMDBhNDYyZi4wMTU3Il0sImVtYWlsIjpbInJ5NzRwMjV4MnZAcHJpdmF0ZXJlbGF5LmFwcGxlaWQuY29tIl19LCJzaWduX2luX3Byb3ZpZGVyIjoiYXBwbGUuY29tIn19.wVpZhw2K9hzusOg9i6WArHRs7B67yqM-mHQyBLtoRK1apUcdZsbQRGI9en2FE4NLX2NowWKEKodMED9OfHQZTWbdo2z2kPXmdCffYF-63zuZWZQ4qJ7Y6yjJ4NSF_AnFbKBYYkvELW91JbPOJGGCn3cRjmKSPU4-5rGobI17J6R_Pt0Eftsw9B3pLoHaIRnW_iS3j1oJ6UweuMI331FOdc8gQkvsd4ahFoE7MvBsSvO2-IhMZcc53m5yavvPGhOoh6kEVNlEcNUQG8s_gbpOBMsROsgl_sgf8TNNUKXaE6iFZdBzIXFQ9QzO1RvZ_JdnGDTIch71BATOcqlP1FRaSg\")",
|
||||
"Bash(xargs:*)",
|
||||
"Bash(chmod:*)",
|
||||
"Bash(docker info:*)",
|
||||
"Bash(docker-compose exec:*)",
|
||||
"Bash(sshpass:*)",
|
||||
"Bash(ssh:*)",
|
||||
"Bash(sort:*)",
|
||||
"Bash(for f in /Users/treyt/Desktop/code/Feeld/ping_calls/profile_update_logs/request_*)",
|
||||
"Bash(find:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
4780
API_DOCUMENTATION.md
Normal file
4780
API_DOCUMENTATION.md
Normal file
File diff suppressed because it is too large
Load Diff
BIN
chat.stream-io-api.com_01-24-2026-11-11-43.proxymanlogv2
Normal file
BIN
chat.stream-io-api.com_01-24-2026-11-11-43.proxymanlogv2
Normal file
Binary file not shown.
379
claude.md
Normal file
379
claude.md
Normal file
@@ -0,0 +1,379 @@
|
||||
# Feeld Web Client
|
||||
|
||||
A React/TypeScript web application that provides browser-based access to the Feeld dating platform. Connects to the same GraphQL backend as the mobile app using Firebase authentication.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
cd web
|
||||
npm install
|
||||
npm run dev:all # Starts both Vite dev server and Express backend
|
||||
```
|
||||
|
||||
- Frontend: http://localhost:3000
|
||||
- Backend API: http://localhost:3001
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
/Feeld
|
||||
├── web/ # Main React application
|
||||
│ ├── src/
|
||||
│ │ ├── api/ # API layer
|
||||
│ │ │ ├── auth.ts # Firebase token management (AuthManager class)
|
||||
│ │ │ ├── client.ts # Apollo GraphQL client setup
|
||||
│ │ │ ├── dataSync.ts # localStorage + server sync service
|
||||
│ │ │ └── operations/ # GraphQL queries and mutations
|
||||
│ │ │ ├── queries.ts
|
||||
│ │ │ ├── mutations.ts
|
||||
│ │ │ └── experimental.ts
|
||||
│ │ ├── components/
|
||||
│ │ │ ├── ui/ # Shared UI primitives
|
||||
│ │ │ │ ├── Avatar.tsx # Profile avatar with fallback
|
||||
│ │ │ │ ├── Badge.tsx # Status/tag badges
|
||||
│ │ │ │ ├── Button.tsx # Styled button component
|
||||
│ │ │ │ ├── Card.tsx # Card container
|
||||
│ │ │ │ ├── Loading.tsx # Loading spinner/skeleton
|
||||
│ │ │ │ └── ProxiedImage.tsx # Image component with proxy URL handling
|
||||
│ │ │ ├── layout/ # Layout and Navigation
|
||||
│ │ │ │ ├── Layout.tsx # Main layout wrapper with nav
|
||||
│ │ │ │ └── Navigation.tsx # Side rail (desktop) / bottom bar (mobile)
|
||||
│ │ │ ├── profile/ # Profile display components
|
||||
│ │ │ │ ├── ProfileCard.tsx # Profile card (used in Likes, Discover, etc.)
|
||||
│ │ │ │ ├── ProfileDetailModal.tsx # Full profile modal with partner nav
|
||||
│ │ │ │ └── PingModal.tsx # Send ping modal with message
|
||||
│ │ │ ├── chat/ # Chat components
|
||||
│ │ │ │ └── ChatListItem.tsx
|
||||
│ │ │ └── LoginPage.tsx
|
||||
│ │ ├── pages/ # Route pages
|
||||
│ │ │ ├── Discover.tsx # Profile discovery feed with scanner
|
||||
│ │ │ ├── Likes.tsx # Likes/Pings/You Liked/Passed (4 tabs)
|
||||
│ │ │ ├── SentPings.tsx # Outbound pings tracker
|
||||
│ │ │ ├── Messages.tsx # Chat list
|
||||
│ │ │ ├── Chat.tsx # Individual conversation
|
||||
│ │ │ ├── Profile.tsx # Own profile view
|
||||
│ │ │ ├── Settings.tsx # App settings
|
||||
│ │ │ └── ApiExplorer.tsx # Debug tool for testing GraphQL
|
||||
│ │ ├── hooks/ # Custom React hooks
|
||||
│ │ │ ├── useAuth.tsx # Authentication context/provider
|
||||
│ │ │ ├── useLocation.tsx # Location context with geocoding
|
||||
│ │ │ ├── useLikedProfiles.ts
|
||||
│ │ │ ├── useDislikedProfiles.ts # Track passed/disliked profiles
|
||||
│ │ │ └── useSentPings.ts # Track outbound pings
|
||||
│ │ ├── context/
|
||||
│ │ │ └── StreamChatContext.tsx # Stream Chat SDK provider
|
||||
│ │ ├── config/
|
||||
│ │ │ └── constants.ts # API URLs, headers, credentials
|
||||
│ │ ├── utils/
|
||||
│ │ │ └── images.ts # Image URL proxying
|
||||
│ │ ├── App.tsx # Root component with providers
|
||||
│ │ └── main.tsx # Entry point
|
||||
│ ├── server/
|
||||
│ │ └── index.js # Express backend for data persistence
|
||||
│ ├── vite.config.ts # Vite bundler config with API proxies
|
||||
│ ├── package.json
|
||||
│ ├── docker-compose.yml # Docker stack for Unraid production
|
||||
│ └── docker-compose.local.yml # Docker stack for local development
|
||||
├── proxyman_extracted/ # Captured API requests/responses
|
||||
├── proxyman_chat/ # Captured Stream Chat API data
|
||||
├── stream_extracted/ # Stream Chat SDK captures
|
||||
└── API_DOCUMENTATION.md # Comprehensive API docs (4780 lines)
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Stack
|
||||
- **React 19** with TypeScript
|
||||
- **Apollo Client 4** for GraphQL
|
||||
- **Stream Chat SDK** for real-time messaging
|
||||
- **Tailwind CSS 4** for styling
|
||||
- **Vite 7** for bundling
|
||||
- **Express 5** for local backend
|
||||
|
||||
### State Management
|
||||
- **React Context** for global state (Auth, StreamChat, Location)
|
||||
- **Apollo Client cache** for GraphQL data
|
||||
- **localStorage** for offline persistence with server sync
|
||||
|
||||
### Provider Hierarchy
|
||||
```tsx
|
||||
<AuthProvider>
|
||||
<ApolloProvider>
|
||||
<StreamChatProvider>
|
||||
<LocationProvider>
|
||||
<BrowserRouter>
|
||||
<Routes />
|
||||
</BrowserRouter>
|
||||
</LocationProvider>
|
||||
</StreamChatProvider>
|
||||
</ApolloProvider>
|
||||
</AuthProvider>
|
||||
```
|
||||
|
||||
## Key Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `web/src/App.tsx` | Root component with all providers |
|
||||
| `web/src/api/client.ts` | Apollo GraphQL client with auth headers |
|
||||
| `web/src/api/auth.ts` | Firebase token refresh (AuthManager singleton) |
|
||||
| `web/src/api/dataSync.ts` | Dual storage: localStorage + backend server |
|
||||
| `web/src/config/constants.ts` | API endpoints, credentials, headers |
|
||||
| `web/src/hooks/useAuth.tsx` | Auth context and login/logout |
|
||||
| `web/src/context/StreamChatContext.tsx` | Stream Chat initialization |
|
||||
| `web/src/components/profile/ProfileCard.tsx` | Profile card with `safeText()` rendering |
|
||||
| `web/src/pages/Likes.tsx` | Likes page with enrichment, scanner, auto-refresh |
|
||||
| `web/server/index.js` | Express backend for data persistence |
|
||||
| `API_DOCUMENTATION.md` | Full API reference from reverse engineering |
|
||||
|
||||
## API Integration
|
||||
|
||||
### GraphQL Backend
|
||||
- **Endpoint**: `https://core.api.fldcore.com/graphql` (proxied via Vite)
|
||||
- **Client**: Apollo Client with auth link middleware
|
||||
- **Key queries**: `ProfileQuery`, `DiscoverProfiles`, `WhoLikesMe`, `ListSummaries`
|
||||
- **Key mutations**: `ProfileLike`, `ProfileDislike`, `DeviceLocationUpdate`, `SearchSettingsUpdate`
|
||||
|
||||
### Required Headers
|
||||
```typescript
|
||||
{
|
||||
'Authorization': 'Bearer <firebase_jwt>',
|
||||
'x-profile-id': 'profile#<uuid>',
|
||||
'x-app-version': '8.8.3',
|
||||
'x-device-os': 'ios',
|
||||
'x-os-version': '18.6.2',
|
||||
'x-transaction-id': '<uuid>',
|
||||
'x-event-analytics-id': '<uuid>'
|
||||
}
|
||||
```
|
||||
|
||||
### Firebase Authentication
|
||||
- Token refresh via `https://securetoken.googleapis.com/v1/token`
|
||||
- AuthManager class handles automatic refresh with 1-minute buffer
|
||||
- Tokens stored in memory, refresh token in localStorage
|
||||
|
||||
### Stream Chat
|
||||
- Real-time messaging via Stream Chat SDK
|
||||
- Credentials fetched via `StreamCredentialsQuery` GraphQL
|
||||
- API Key: `y4tp4akjeb49`
|
||||
|
||||
### Local Backend Endpoints
|
||||
```
|
||||
GET/PUT /api/data/:userId # Full user data
|
||||
GET/PUT /api/data/:userId/:key # Specific key
|
||||
DELETE /api/data/:userId/:key # Delete key
|
||||
POST /api/data/:userId/liked-profiles
|
||||
DELETE /api/data/:userId/liked-profiles/:profileId
|
||||
GET/POST /api/disliked-profiles # Passed/disliked profiles cache
|
||||
DELETE /api/disliked-profiles/:id # Remove from passed
|
||||
GET/POST /api/who-liked-you # Cache profiles that liked user
|
||||
GET/POST /api/sent-pings # Track outbound pings
|
||||
PUT /api/sent-pings/:targetProfileId # Update ping status
|
||||
DELETE /api/sent-pings/:targetProfileId # Remove sent ping
|
||||
POST /api/auth/login
|
||||
GET /api/auth/verify
|
||||
POST /api/auth/logout
|
||||
GET /api/health
|
||||
```
|
||||
|
||||
## Data Persistence
|
||||
|
||||
Hybrid localStorage + server approach in `dataSync.ts`:
|
||||
1. **Write**: localStorage immediately → sync to server
|
||||
2. **Read**: Try server first → fallback to localStorage
|
||||
3. **Health check**: Server ping every 30 seconds
|
||||
|
||||
Keys synced: `liked_profiles`, `disliked_profiles`, `who_liked_you_profiles`, `locations`, `credentials`, `current_location`, `analytics_id`
|
||||
|
||||
## Routes
|
||||
|
||||
| Path | Page | Description |
|
||||
|------|------|-------------|
|
||||
| `/discover` | DiscoverPage | Profile discovery feed with scanner |
|
||||
| `/likes` | LikesPage | Likes / Pings / You Liked / Passed (4 tabs) |
|
||||
| `/sent-pings` | SentPingsPage | Outbound pings tracker |
|
||||
| `/messages` | MessagesPage | Chat conversation list |
|
||||
| `/chat/:channelId` | ChatPage | Individual chat |
|
||||
| `/profile` | ProfilePage | Own profile view |
|
||||
| `/settings` | SettingsPage | Location, search settings, credentials |
|
||||
| `/api-explorer` | ApiExplorerPage | Debug tool for testing GraphQL queries |
|
||||
|
||||
## Development
|
||||
|
||||
### Scripts
|
||||
```bash
|
||||
npm run dev # Vite dev server only
|
||||
npm run server # Express backend only
|
||||
npm run dev:all # Both in parallel (recommended)
|
||||
npm run build # Production build
|
||||
npm run lint # ESLint check
|
||||
npm run docker:local # Start local Docker stack
|
||||
npm run docker:local:down # Stop local Docker stack
|
||||
npm run docker:local:logs # View local Docker logs
|
||||
```
|
||||
|
||||
### Vite Proxy Configuration
|
||||
The Vite dev server proxies requests to bypass CORS:
|
||||
|
||||
**External APIs:**
|
||||
- `/api/graphql` → `core.api.fldcore.com` (GraphQL backend)
|
||||
- `/api/firebase` → `securetoken.googleapis.com` (auth tokens)
|
||||
- `/api/images` → `res.cloudinary.com` (profile images)
|
||||
- `/api/fldcdn` → `prod.fldcdn.com` (CDN assets)
|
||||
|
||||
**Local backend:**
|
||||
- `/api/who-liked-you` → `localhost:3001`
|
||||
- `/api/sent-pings` → `localhost:3001`
|
||||
- `/api/disliked-profiles` → `localhost:3001`
|
||||
- `/api/data` → `localhost:3001`
|
||||
- `/api/auth` → `localhost:3001`
|
||||
- `/api/health` → `localhost:3001`
|
||||
|
||||
Mobile app User-Agent is injected on external proxies to bypass hotlink protection.
|
||||
|
||||
### Docker
|
||||
|
||||
Two compose files:
|
||||
- **`docker-compose.yml`** - Production config for Unraid server (absolute paths to `/mnt/user/appdata/FeeldWeb`)
|
||||
- **`docker-compose.local.yml`** - Local dev config (relative paths)
|
||||
|
||||
```bash
|
||||
# Local development
|
||||
docker compose -f docker-compose.local.yml up -d --build
|
||||
|
||||
# Production (on Unraid server)
|
||||
cd /mnt/user/appdata/FeeldWeb && docker compose up -d --build
|
||||
```
|
||||
- Frontend: port 3000 (Vite dev server)
|
||||
- Backend: port 3001 (Express)
|
||||
- Nginx: port 7743 (reverse proxy)
|
||||
|
||||
## Testing
|
||||
|
||||
No automated tests currently. Manual testing via:
|
||||
- `/api-explorer` route for GraphQL query testing
|
||||
- Console logging throughout codebase
|
||||
- `/api/health` endpoint for backend status
|
||||
|
||||
## Credentials & Configuration
|
||||
|
||||
Credentials are stored in `constants.ts` and localStorage:
|
||||
- `feeld_profile_id` - Current profile UUID
|
||||
- `feeld_refresh_token` - Firebase refresh token
|
||||
- `feeld_auth_token` - Current session token
|
||||
- `feeld_analytics_id` - Event tracking ID
|
||||
|
||||
## Features
|
||||
|
||||
### Likes Page (4 Tabs)
|
||||
- **Likes**: Profiles that have liked you, enriched with cached data from `/api/who-liked-you`
|
||||
- **Pings**: Profiles that pinged you (liked with a message)
|
||||
- **You Liked**: Profiles you've liked
|
||||
- **Passed**: Profiles you've disliked/passed on, stored via `/api/disliked-profiles`
|
||||
|
||||
**Enrichment**: WhoLikesMe API returns limited data (null photos for non-Majestic users). Cached profile data from the scanner (Discover API) is merged in via `useMemo`. Older likes (further down the list) get matched first to preserve chronological accuracy when multiple people share the same name.
|
||||
|
||||
**Auto-refresh**: On page load, profiles with missing/expired photos are automatically refreshed via individual `ProfileQuery` calls. Uses `useRef` + `sessionStorage` to prevent crash-remount loops (React error unmounts/remounts the component, resetting `useState` but not `useRef`/`sessionStorage`).
|
||||
|
||||
**Scanner**: Scans multiple saved locations via the Discover API to find real profile data. "Fuck It" mode scans all saved locations. Profiles that have liked you are auto-saved to `/api/who-liked-you`.
|
||||
|
||||
### Profile Detail Modal
|
||||
- View full profile details including photos, bio, desires, interests
|
||||
- **Partner navigation**: Click on linked partner profiles to view their details
|
||||
- Back button to return to previous profile when viewing partners
|
||||
- Like/Dislike actions with API mutations
|
||||
- Ping modal for sending messages with likes
|
||||
|
||||
### Discover Page
|
||||
- Profile browsing with like/dislike/ping actions
|
||||
- Auto-saves profiles that have liked you (detected via `interactionStatus.theirs === 'LIKED'`)
|
||||
- Profiles cached to `/api/who-liked-you` for enriching Likes page data
|
||||
|
||||
### Sent Pings Page
|
||||
- Tracks outbound pings (likes with messages) sent to other profiles
|
||||
- Shows ping message, target profile, and status
|
||||
- Stored via `/api/sent-pings` backend endpoint
|
||||
|
||||
## Gotchas
|
||||
|
||||
### GraphQL `__typename` Objects
|
||||
The Feeld GraphQL API can return profile fields (gender, sexuality, location, goals, distance) as objects with `{__typename: "..."}` instead of plain strings. **Always use `safeText()` or type checks when rendering any profile field.** Never render `profile.gender` or similar fields directly in JSX.
|
||||
|
||||
```tsx
|
||||
// ProfileCard.tsx has a safeText() helper:
|
||||
const safeText = (v: any): string => {
|
||||
if (v == null) return '';
|
||||
if (typeof v === 'string') return v;
|
||||
if (typeof v === 'number' || typeof v === 'boolean') return String(v);
|
||||
return '';
|
||||
};
|
||||
|
||||
// Usage: <span>{safeText(profile.gender)}</span>
|
||||
// NOT: <span>{profile.gender}</span> // Can crash with "Objects are not valid as React child"
|
||||
```
|
||||
|
||||
Also sanitize profile data before saving to backend cache with `safeStr()`:
|
||||
```tsx
|
||||
const safeStr = (v: any) => (typeof v === 'string' ? v : '');
|
||||
```
|
||||
|
||||
### Signed Image URLs
|
||||
Cloudinary/fldcdn signed image URLs expire after a few hours. Cached profiles need periodic refresh to get new URLs. The auto-refresh on the Likes page handles this.
|
||||
|
||||
### API Version Enforcement
|
||||
Feeld API enforces `x-app-version` — old versions get `UNSUPPORTED_APP_VERSION` 400 errors. Check the App Store for the current version and update `constants.ts` and `vite.config.ts` headers.
|
||||
|
||||
### WhoLikesMe Photo Limitations
|
||||
WhoLikesMe API returns null photo URLs for non-Majestic (non-paying) users. The scanner (Discover API) returns real photos, which is why we cache scanner results and enrich WhoLikesMe data.
|
||||
|
||||
### Render-time Side Effects
|
||||
Never call functions with side effects during React render. Use `useMemo` for data transformation and separate `useEffect` for side effects like API calls or cache updates. Calling side-effect functions during render causes infinite re-render loops.
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Add a new page
|
||||
1. Create component in `web/src/pages/`
|
||||
2. Add route in `web/src/App.tsx`
|
||||
3. Add navigation link in `web/src/components/layout/Navigation.tsx`
|
||||
|
||||
### Add a new GraphQL query/mutation
|
||||
1. Define in `web/src/api/operations/queries.ts` or `mutations.ts`
|
||||
2. Use fragments from existing definitions for consistency
|
||||
3. Call via Apollo's `useQuery`/`useMutation` hooks
|
||||
|
||||
### Add a new context/hook
|
||||
1. Create in `web/src/hooks/` or `web/src/context/`
|
||||
2. Export provider and hook
|
||||
3. Add provider to hierarchy in `App.tsx`
|
||||
|
||||
### Debug API issues
|
||||
1. Use `/api-explorer` route to test queries directly
|
||||
2. Check Network tab for request/response
|
||||
3. Verify headers in `constants.ts`
|
||||
4. Check `API_DOCUMENTATION.md` for endpoint details
|
||||
|
||||
## Remote Deployment (Unraid)
|
||||
|
||||
Production runs on an Unraid server at `10.3.3.11`. Code lives at `/mnt/user/appdata/FeeldWeb/`, persistent data at `/mnt/user/downloads/feeldWeb/`.
|
||||
|
||||
```bash
|
||||
# SSH in
|
||||
sshpass -p 'Intel22' ssh -o StrictHostKeyChecking=no root@10.3.3.11
|
||||
|
||||
# Sync a file
|
||||
sshpass -p 'Intel22' scp -o StrictHostKeyChecking=no \
|
||||
"web/FILE_PATH" "root@10.3.3.11:/mnt/user/appdata/FeeldWeb/FILE_PATH"
|
||||
|
||||
# Restart containers
|
||||
sshpass -p 'Intel22' ssh -o StrictHostKeyChecking=no root@10.3.3.11 \
|
||||
'docker restart feeld-web-frontend feeld-web-backend feeld-web-nginx'
|
||||
```
|
||||
|
||||
External URL: https://feeld.treytartt.com (proxied via Nginx Proxy Manager on port 7743)
|
||||
|
||||
## External Resources
|
||||
|
||||
- **API Documentation**: `API_DOCUMENTATION.md` (comprehensive reverse-engineered docs)
|
||||
- **Captured Requests**: `proxyman_extracted/`, `proxyman_chat/`, `stream_extracted/`
|
||||
- **Stream Chat Docs**: https://getstream.io/chat/docs/
|
||||
- **Apollo Client Docs**: https://www.apollographql.com/docs/react/
|
||||
BIN
core.api.fldcore.com_01-24-2026-05-31-58.proxymanlogv2
Normal file
BIN
core.api.fldcore.com_01-24-2026-05-31-58.proxymanlogv2
Normal file
Binary file not shown.
BIN
core.api.fldcore.com_01-24-2026-05-50-44.proxymanlogv2
Normal file
BIN
core.api.fldcore.com_01-24-2026-05-50-44.proxymanlogv2
Normal file
Binary file not shown.
BIN
core.api.fldcore.com_01-24-2026-06-57-56.proxymanlogv2
Normal file
BIN
core.api.fldcore.com_01-24-2026-06-57-56.proxymanlogv2
Normal file
Binary file not shown.
BIN
core.api.fldcore.com_01-24-2026-10-36-00.proxymanlogv2
Normal file
BIN
core.api.fldcore.com_01-24-2026-10-36-00.proxymanlogv2
Normal file
Binary file not shown.
BIN
core.api.fldcore.com_01-24-2026-11-10-49.proxymanlogv2
Normal file
BIN
core.api.fldcore.com_01-24-2026-11-10-49.proxymanlogv2
Normal file
Binary file not shown.
114
docker-compose.unraid.yml
Normal file
114
docker-compose.unraid.yml
Normal file
@@ -0,0 +1,114 @@
|
||||
# Docker Compose for Unraid
|
||||
#
|
||||
# Access at http://YOUR_UNRAID_IP:8580
|
||||
#
|
||||
# ============================================
|
||||
# CONFIGURE THESE PATHS FOR YOUR UNRAID SETUP
|
||||
# ============================================
|
||||
# Edit the left side of the colon (:) for each volume mount
|
||||
#
|
||||
# DATABASE_PATH: Where to store the SQLite database
|
||||
# IMAGES_PATH: Where to store downloaded images (can be large, 100GB+)
|
||||
# EXPORTS_PATH: Where to store generated export zip files
|
||||
# IMPORTS_PATH: Where to place images for bulk import (source/species/images)
|
||||
# LOGS_PATH: Where to store scraper log files for debugging
|
||||
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: /mnt/user/appdata/PlantGuideScraper/backend
|
||||
dockerfile: Dockerfile
|
||||
container_name: plant-scraper-backend
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /mnt/user/appdata/PlantGuideScraper/backend:/app:ro
|
||||
# === CONFIGURABLE DATA PATHS ===
|
||||
- /mnt/user/downloads/PlantGuideDocker/database:/data/db # DATABASE_PATH
|
||||
- /mnt/user/downloads/PlantGuideDocker/images:/data/images # IMAGES_PATH
|
||||
- /mnt/user/downloads/PlantGuideDocker/exports:/data/exports # EXPORTS_PATH
|
||||
- /mnt/user/downloads/PlantGuideDocker/imports:/data/imports # IMPORTS_PATH
|
||||
- /mnt/user/downloads/PlantGuideDocker/logs:/data/logs # LOGS_PATH
|
||||
environment:
|
||||
- DATABASE_URL=sqlite:////data/db/plants.sqlite
|
||||
- REDIS_URL=redis://plant-scraper-redis:6379/0
|
||||
- IMAGES_PATH=/data/images
|
||||
- EXPORTS_PATH=/data/exports
|
||||
- IMPORTS_PATH=/data/imports
|
||||
- LOGS_PATH=/data/logs
|
||||
depends_on:
|
||||
- redis
|
||||
command: uvicorn app.main:app --host 0.0.0.0 --port 8000
|
||||
networks:
|
||||
- plant-scraper
|
||||
|
||||
celery:
|
||||
build:
|
||||
context: /mnt/user/appdata/PlantGuideScraper/backend
|
||||
dockerfile: Dockerfile
|
||||
container_name: plant-scraper-celery
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /mnt/user/appdata/PlantGuideScraper/backend:/app:ro
|
||||
# === CONFIGURABLE DATA PATHS (must match backend) ===
|
||||
- /mnt/user/downloads/PlantGuideDocker/database:/data/db # DATABASE_PATH
|
||||
- /mnt/user/downloads/PlantGuideDocker/images:/data/images # IMAGES_PATH
|
||||
- /mnt/user/downloads/PlantGuideDocker/exports:/data/exports # EXPORTS_PATH
|
||||
- /mnt/user/downloads/PlantGuideDocker/imports:/data/imports # IMPORTS_PATH
|
||||
- /mnt/user/downloads/PlantGuideDocker/logs:/data/logs # LOGS_PATH
|
||||
environment:
|
||||
- DATABASE_URL=sqlite:////data/db/plants.sqlite
|
||||
- REDIS_URL=redis://plant-scraper-redis:6379/0
|
||||
- IMAGES_PATH=/data/images
|
||||
- EXPORTS_PATH=/data/exports
|
||||
- IMPORTS_PATH=/data/imports
|
||||
- LOGS_PATH=/data/logs
|
||||
depends_on:
|
||||
- redis
|
||||
command: celery -A app.workers.celery_app worker --beat --loglevel=info --concurrency=4
|
||||
networks:
|
||||
- plant-scraper
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: plant-scraper-redis
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /mnt/user/appdata/PlantGuideScraper/redis:/data
|
||||
networks:
|
||||
- plant-scraper
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: /mnt/user/appdata/PlantGuideScraper/frontend
|
||||
dockerfile: Dockerfile
|
||||
container_name: plant-scraper-frontend
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /mnt/user/appdata/PlantGuideScraper/frontend:/app
|
||||
- plant-scraper-node-modules:/app/node_modules
|
||||
environment:
|
||||
- VITE_API_URL=
|
||||
command: npm run dev -- --host
|
||||
networks:
|
||||
- plant-scraper
|
||||
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: plant-scraper-nginx
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8580:80"
|
||||
volumes:
|
||||
- /mnt/user/appdata/PlantGuideScraper/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
depends_on:
|
||||
- backend
|
||||
- frontend
|
||||
networks:
|
||||
- plant-scraper
|
||||
|
||||
networks:
|
||||
plant-scraper:
|
||||
name: plant-scraper
|
||||
|
||||
volumes:
|
||||
plant-scraper-node-modules:
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -0,0 +1 @@
|
||||
{"endAt":791306209.6549392,"requestEndAt":1769613409.6549392,"timezone":"CST","isIntercepted":true,"name":"128","fileName":null,"websocketMessageStorage":null,"uniqueID":null,"timing":{"responseEndedAt":1769613409.6549392,"requestStartedAt":1769613409.524766,"requestEndedAt":1769613409.6549392,"responseStartedAt":1769613409.654933},"response":{"createdAt":1769613409.654933,"customPreviewerTabs":null,"version":{"major":1,"minor":1},"bodyData":null,"compressedBodyDataCount":0,"error":null,"header":{"entries":[{"value":"upgrade","key":{"nameInLowercase":"connection","name":"Connection"},"isEnabled":true},{"key":{"name":"Date","nameInLowercase":"date"},"value":"Wed, 28 Jan 2026 15:16:49 GMT","isEnabled":true},{"key":{"name":"Upgrade","nameInLowercase":"upgrade"},"value":"websocket","isEnabled":true},{"key":{"name":"Sec-WebSocket-Accept","nameInLowercase":"sec-websocket-accept"},"value":"fXS1ZX2H7nxscNAKe1\/fkCsgy5o=","isEnabled":true},{"key":{"nameInLowercase":"sec-websocket-protocol","name":"Sec-WebSocket-Protocol"},"value":"graphql-transport-ws","isEnabled":true},{"key":{"nameInLowercase":"x-cache","name":"X-Cache"},"value":"Miss from cloudfront","isEnabled":true},{"key":{"name":"Via","nameInLowercase":"via"},"value":"1.1 51d0a1b74b16c30679726a1e0d574f5c.cloudfront.net (CloudFront)","isEnabled":true},{"key":{"nameInLowercase":"x-amz-cf-pop","name":"X-Amz-Cf-Pop"},"value":"DFW56-P10","isEnabled":true},{"key":{"name":"X-Amz-Cf-Id","nameInLowercase":"x-amz-cf-id"},"value":"xFILIXQ2sz0DHKsjlwIj20I82E5aIOgd504imMt5owVzDfNvAoUX_A==","isEnabled":true},{"key":{"nameInLowercase":"access-control-allow-origin","name":"Access-Control-Allow-Origin"},"value":"*","isEnabled":true}]},"status":{"strict":false,"phrase":"Switching Protocols","code":101}},"isFromFile":false,"proxyCreatedAt":1769613409.524766,"style":null,"request":{"method":{"name":"GET"},"compressedBodyDataCount":0,"host":"core.api.fldcore.com","version":{"major":1,"minor":1},"isSSL":true,"bodyData":null,"header":{"entries":[{"isEnabled":true,"key":{"name":"Host","nameInLowercase":"host"},"value":"core.api.fldcore.com"},{"isEnabled":true,"key":{"name":"Sec-WebSocket-Protocol","nameInLowercase":"sec-websocket-protocol"},"value":"graphql-transport-ws"},{"isEnabled":true,"key":{"nameInLowercase":"sec-websocket-key","name":"Sec-WebSocket-Key"},"value":"8bu\/ZEvnkXG30xUxkXTbAQ=="},{"isEnabled":true,"key":{"nameInLowercase":"sec-websocket-version","name":"Sec-WebSocket-Version"},"value":"13"},{"isEnabled":true,"key":{"name":"Upgrade","nameInLowercase":"upgrade"},"value":"websocket"},{"key":{"name":"Origin","nameInLowercase":"origin"},"isEnabled":true,"value":"https:\/\/core.api.fldcore.com"},{"key":{"name":"User-Agent","nameInLowercase":"user-agent"},"isEnabled":true,"value":"feeld-mobile"},{"key":{"name":"Connection","nameInLowercase":"connection"},"isEnabled":true,"value":"Upgrade"}]},"isWebSocketUpgrade":true,"scheme":"wss","uri":"\/subscription","fullPath":"wss:\/\/core.api.fldcore.com\/subscription","port":443,"customPreviewerTabs":null},"isSSL":true,"id":"128","summary":{"clientPort":58374,"clientIpAddress":"127.0.0.1","serverIpAddress":"13.249.205.128","serverPort":443,"hostDNS":null,"tag":null},"client":null,"createAt":1769613409.524766,"isUnderNetworkCondition":false,"extraInfo":null,"toolMetadata":null,"isRelayed":false,"remoteDevice":{"ip":"127.0.0.1","name":"127.0.0.1"}}
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"isIntercepted":true,"client":null,"id":"195","websocketMessageStorage":null,"summary":{"hostDNS":null,"tag":null,"clientPort":58489,"clientIpAddress":"127.0.0.1","serverIpAddress":"52.84.20.111","serverPort":443},"uniqueID":null,"isFromFile":false,"isSSL":true,"request":{"port":443,"host":"core.api.fldcore.com","customPreviewerTabs":null,"header":{"entries":[{"key":{"nameInLowercase":"host","name":"Host"},"value":"core.api.fldcore.com","isEnabled":true},{"key":{"name":"Sec-WebSocket-Protocol","nameInLowercase":"sec-websocket-protocol"},"value":"graphql-transport-ws","isEnabled":true},{"key":{"name":"Sec-WebSocket-Key","nameInLowercase":"sec-websocket-key"},"value":"k0DR\/N9CDih3sgDU0N1mnA==","isEnabled":true},{"key":{"name":"Sec-WebSocket-Version","nameInLowercase":"sec-websocket-version"},"value":"13","isEnabled":true},{"key":{"nameInLowercase":"upgrade","name":"Upgrade"},"value":"websocket","isEnabled":true},{"key":{"nameInLowercase":"origin","name":"Origin"},"value":"https:\/\/core.api.fldcore.com","isEnabled":true},{"key":{"name":"User-Agent","nameInLowercase":"user-agent"},"value":"feeld-mobile","isEnabled":true},{"key":{"name":"Connection","nameInLowercase":"connection"},"value":"Upgrade","isEnabled":true}]},"fullPath":"wss:\/\/core.api.fldcore.com\/subscription","isSSL":true,"bodyData":null,"uri":"\/subscription","compressedBodyDataCount":0,"isWebSocketUpgrade":true,"method":{"name":"GET"},"version":{"minor":1,"major":1},"scheme":"wss"},"createAt":1769615178.7193441,"response":{"version":{"major":1,"minor":1},"bodyData":null,"compressedBodyDataCount":0,"error":null,"header":{"entries":[{"value":"upgrade","key":{"name":"Connection","nameInLowercase":"connection"},"isEnabled":true},{"value":"Wed, 28 Jan 2026 15:46:19 GMT","key":{"name":"Date","nameInLowercase":"date"},"isEnabled":true},{"value":"websocket","key":{"name":"Upgrade","nameInLowercase":"upgrade"},"isEnabled":true},{"value":"V2XEVJk2qtuHtYjszipvCJkL09U=","key":{"name":"Sec-WebSocket-Accept","nameInLowercase":"sec-websocket-accept"},"isEnabled":true},{"value":"graphql-transport-ws","key":{"name":"Sec-WebSocket-Protocol","nameInLowercase":"sec-websocket-protocol"},"isEnabled":true},{"value":"Miss from cloudfront","key":{"name":"X-Cache","nameInLowercase":"x-cache"},"isEnabled":true},{"value":"1.1 58ea7d14c4c1fcd2d3e94e640c0a2236.cloudfront.net (CloudFront)","key":{"name":"Via","nameInLowercase":"via"},"isEnabled":true},{"value":"LAX53-P5","key":{"nameInLowercase":"x-amz-cf-pop","name":"X-Amz-Cf-Pop"},"isEnabled":true},{"value":"JXqLaVJXpQw70bwS8ByMIqUgCf5qDyBCB0Sk6C62gk9Lqhp-PNjUhQ==","key":{"nameInLowercase":"x-amz-cf-id","name":"X-Amz-Cf-Id"},"isEnabled":true},{"value":"*","key":{"nameInLowercase":"access-control-allow-origin","name":"Access-Control-Allow-Origin"},"isEnabled":true}]},"createdAt":1769615179.051711,"customPreviewerTabs":null,"status":{"strict":false,"phrase":"Switching Protocols","code":101}},"proxyCreatedAt":1769615178.7193441,"isUnderNetworkCondition":false,"timing":{"responseStartedAt":1769615179.051711,"responseEndedAt":1769615179.051713,"requestEndedAt":1769615179.051713,"requestStartedAt":1769615178.7193441},"extraInfo":null,"isRelayed":false,"style":null,"toolMetadata":null,"remoteDevice":{"name":"127.0.0.1","ip":"127.0.0.1"},"endAt":791307979.051713,"fileName":null,"name":"195","timezone":"CST","requestEndAt":1769615179.051713}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
1
ping_calls/profile_update_logs/request_464
Normal file
1
ping_calls/profile_update_logs/request_464
Normal file
File diff suppressed because one or more lines are too long
1
ping_calls/profile_update_logs/request_465
Normal file
1
ping_calls/profile_update_logs/request_465
Normal file
File diff suppressed because one or more lines are too long
1
ping_calls/profile_update_logs/request_467
Normal file
1
ping_calls/profile_update_logs/request_467
Normal file
@@ -0,0 +1 @@
|
||||
{"extraInfo":null,"isRelayed":false,"isSSL":true,"summary":{"serverIpAddress":"13.249.205.39","hostDNS":null,"tag":null,"serverPort":443,"clientIpAddress":"127.0.0.1","clientPort":58972},"isFromFile":false,"uniqueID":null,"timezone":"CST","requestEndAt":1769621453.599446,"toolMetadata":null,"isUnderNetworkCondition":false,"websocketMessageStorage":null,"id":"467","remoteDevice":{"ip":"127.0.0.1","name":"127.0.0.1"},"client":null,"endAt":791314253.599446,"name":"467","request":{"isSSL":true,"compressedBodyDataCount":0,"isWebSocketUpgrade":true,"header":{"entries":[{"key":{"nameInLowercase":"host","name":"Host"},"value":"core.api.fldcore.com","isEnabled":true},{"key":{"nameInLowercase":"sec-websocket-protocol","name":"Sec-WebSocket-Protocol"},"value":"graphql-transport-ws","isEnabled":true},{"key":{"nameInLowercase":"sec-websocket-key","name":"Sec-WebSocket-Key"},"value":"6Bi\/7ocVw8sTNYnI+SaH9A==","isEnabled":true},{"key":{"nameInLowercase":"sec-websocket-version","name":"Sec-WebSocket-Version"},"value":"13","isEnabled":true},{"key":{"nameInLowercase":"upgrade","name":"Upgrade"},"value":"websocket","isEnabled":true},{"key":{"nameInLowercase":"origin","name":"Origin"},"value":"https:\/\/core.api.fldcore.com","isEnabled":true},{"key":{"nameInLowercase":"user-agent","name":"User-Agent"},"value":"feeld-mobile","isEnabled":true},{"key":{"nameInLowercase":"connection","name":"Connection"},"value":"Upgrade","isEnabled":true}]},"version":{"minor":1,"major":1},"uri":"\/subscription","fullPath":"wss:\/\/core.api.fldcore.com\/subscription","method":{"name":"GET"},"customPreviewerTabs":null,"scheme":"wss","port":443,"bodyData":null,"host":"core.api.fldcore.com"},"style":null,"fileName":null,"response":{"createdAt":1769621453.599441,"compressedBodyDataCount":0,"status":{"phrase":"Switching Protocols","strict":false,"code":101},"version":{"minor":1,"major":1},"error":null,"header":{"entries":[{"key":{"nameInLowercase":"connection","name":"Connection"},"value":"upgrade","isEnabled":true},{"key":{"nameInLowercase":"date","name":"Date"},"value":"Wed, 28 Jan 2026 17:30:53 GMT","isEnabled":true},{"key":{"nameInLowercase":"upgrade","name":"Upgrade"},"value":"websocket","isEnabled":true},{"key":{"nameInLowercase":"sec-websocket-accept","name":"Sec-WebSocket-Accept"},"value":"iimrBcfHnP7lkZUE8M4hWo6Vz6Y=","isEnabled":true},{"key":{"nameInLowercase":"sec-websocket-protocol","name":"Sec-WebSocket-Protocol"},"value":"graphql-transport-ws","isEnabled":true},{"key":{"nameInLowercase":"x-cache","name":"X-Cache"},"value":"Miss from cloudfront","isEnabled":true},{"key":{"nameInLowercase":"via","name":"Via"},"value":"1.1 2d6372565e269658e59fe35e195ee728.cloudfront.net (CloudFront)","isEnabled":true},{"key":{"nameInLowercase":"x-amz-cf-pop","name":"X-Amz-Cf-Pop"},"value":"DFW56-P10","isEnabled":true},{"key":{"nameInLowercase":"x-amz-cf-id","name":"X-Amz-Cf-Id"},"value":"I0shX1_gISI2uHTOxa8EK2jyPP4RRbhEo6UKD6dbGGMDIpzv4l43fg==","isEnabled":true},{"key":{"nameInLowercase":"access-control-allow-origin","name":"Access-Control-Allow-Origin"},"value":"*","isEnabled":true}]},"customPreviewerTabs":null,"bodyData":null},"createAt":1769621453.446475,"proxyCreatedAt":1769621453.446475,"timing":{"requestStartedAt":1769621453.446475,"responseStartedAt":1769621453.599441,"responseEndedAt":1769621453.599446,"requestEndedAt":1769621453.599446},"isIntercepted":true}
|
||||
1
ping_calls/profile_update_logs/request_470
Normal file
1
ping_calls/profile_update_logs/request_470
Normal file
File diff suppressed because one or more lines are too long
1
ping_calls/profile_update_logs/request_471
Normal file
1
ping_calls/profile_update_logs/request_471
Normal file
File diff suppressed because one or more lines are too long
1
ping_calls/profile_update_logs/request_473
Normal file
1
ping_calls/profile_update_logs/request_473
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_434
Normal file
1
proxyman_chat/request_434
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_435
Normal file
1
proxyman_chat/request_435
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_436
Normal file
1
proxyman_chat/request_436
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_437
Normal file
1
proxyman_chat/request_437
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_438
Normal file
1
proxyman_chat/request_438
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_439
Normal file
1
proxyman_chat/request_439
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_440
Normal file
1
proxyman_chat/request_440
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_443
Normal file
1
proxyman_chat/request_443
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_444
Normal file
1
proxyman_chat/request_444
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_445
Normal file
1
proxyman_chat/request_445
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_446
Normal file
1
proxyman_chat/request_446
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_447
Normal file
1
proxyman_chat/request_447
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_448
Normal file
1
proxyman_chat/request_448
Normal file
@@ -0,0 +1 @@
|
||||
{"fileName":null,"requestEndAt":1769272531.1225991,"isSSL":true,"proxyCreatedAt":1769272531.00792,"id":"448","summary":{"tag":null,"serverIpAddress":"13.249.205.36","clientPort":50370,"hostDNS":null,"serverPort":443,"clientIpAddress":"127.0.0.1"},"toolMetadata":null,"name":"448","isRelayed":false,"response":{"customPreviewerTabs":null,"status":{"code":101,"strict":false,"phrase":"Switching Protocols"},"header":{"entries":[{"key":{"name":"Connection","nameInLowercase":"connection"},"value":"upgrade","isEnabled":true},{"key":{"name":"Date","nameInLowercase":"date"},"value":"Sat, 24 Jan 2026 16:35:31 GMT","isEnabled":true},{"key":{"name":"Upgrade","nameInLowercase":"upgrade"},"value":"websocket","isEnabled":true},{"key":{"name":"Sec-WebSocket-Accept","nameInLowercase":"sec-websocket-accept"},"value":"VlKG0B7TEj4q076XVRYJT6kzhRE=","isEnabled":true},{"key":{"name":"Sec-WebSocket-Protocol","nameInLowercase":"sec-websocket-protocol"},"value":"graphql-transport-ws","isEnabled":true},{"key":{"name":"X-Cache","nameInLowercase":"x-cache"},"value":"Miss from cloudfront","isEnabled":true},{"key":{"name":"Via","nameInLowercase":"via"},"value":"1.1 380fc6a906659ffac1234c1391eafb90.cloudfront.net (CloudFront)","isEnabled":true},{"key":{"name":"X-Amz-Cf-Pop","nameInLowercase":"x-amz-cf-pop"},"value":"DFW56-P10","isEnabled":true},{"key":{"name":"X-Amz-Cf-Id","nameInLowercase":"x-amz-cf-id"},"value":"erjaD39k06fdEiseWwKn0meTZ8ZxGVAdlrDr5RQJyX6tdBuRLI46qg==","isEnabled":true},{"key":{"name":"Access-Control-Allow-Origin","nameInLowercase":"access-control-allow-origin"},"value":"*","isEnabled":true}]},"createdAt":1769272531.122596,"bodyData":null,"version":{"major":1,"minor":1},"error":null,"compressedBodyDataCount":0},"createAt":1769272531.00792,"isUnderNetworkCondition":false,"client":null,"style":null,"extraInfo":null,"remoteDevice":{"ip":"127.0.0.1","name":"127.0.0.1"},"endAt":790965331.1225991,"uniqueID":null,"timing":{"requestEndedAt":1769272531.1225991,"responseStartedAt":1769272531.122596,"requestStartedAt":1769272531.00792,"responseEndedAt":1769272531.1225991},"websocketMessageStorage":null,"request":{"uri":"\/subscription","header":{"entries":[{"key":{"name":"Host","nameInLowercase":"host"},"value":"core.api.fldcore.com","isEnabled":true},{"key":{"name":"Sec-WebSocket-Protocol","nameInLowercase":"sec-websocket-protocol"},"value":"graphql-transport-ws","isEnabled":true},{"key":{"name":"Sec-WebSocket-Key","nameInLowercase":"sec-websocket-key"},"value":"ZLjXfJWfIp\/yRNTCsF7ZXg==","isEnabled":true},{"key":{"name":"Sec-WebSocket-Version","nameInLowercase":"sec-websocket-version"},"value":"13","isEnabled":true},{"key":{"name":"Upgrade","nameInLowercase":"upgrade"},"value":"websocket","isEnabled":true},{"key":{"name":"Origin","nameInLowercase":"origin"},"value":"https:\/\/core.api.fldcore.com","isEnabled":true},{"key":{"name":"User-Agent","nameInLowercase":"user-agent"},"value":"feeld-mobile","isEnabled":true},{"key":{"name":"Connection","nameInLowercase":"connection"},"value":"Upgrade","isEnabled":true}]},"isSSL":true,"isWebSocketUpgrade":true,"fullPath":"wss:\/\/core.api.fldcore.com\/subscription","scheme":"wss","version":{"major":1,"minor":1},"compressedBodyDataCount":0,"customPreviewerTabs":null,"port":443,"method":{"name":"GET"},"bodyData":null,"host":"core.api.fldcore.com"},"isIntercepted":true,"timezone":"CST","isFromFile":false}
|
||||
1
proxyman_chat/request_449
Normal file
1
proxyman_chat/request_449
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_451
Normal file
1
proxyman_chat/request_451
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_452
Normal file
1
proxyman_chat/request_452
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_453
Normal file
1
proxyman_chat/request_453
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_454
Normal file
1
proxyman_chat/request_454
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_455
Normal file
1
proxyman_chat/request_455
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_457
Normal file
1
proxyman_chat/request_457
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_459
Normal file
1
proxyman_chat/request_459
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_460
Normal file
1
proxyman_chat/request_460
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_461
Normal file
1
proxyman_chat/request_461
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_462
Normal file
1
proxyman_chat/request_462
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_463
Normal file
1
proxyman_chat/request_463
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_464
Normal file
1
proxyman_chat/request_464
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_465
Normal file
1
proxyman_chat/request_465
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_468
Normal file
1
proxyman_chat/request_468
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_469
Normal file
1
proxyman_chat/request_469
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_chat/request_470
Normal file
1
proxyman_chat/request_470
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_extracted/request_175
Normal file
1
proxyman_extracted/request_175
Normal file
File diff suppressed because one or more lines are too long
1
proxyman_extracted/request_176
Normal file
1
proxyman_extracted/request_176
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user