Commit Graph

21 Commits

Author SHA1 Message Date
ga
aee85c0087 Fix: Nearby struct без JSON-тегов → отдавалось PascalCase
После Sprint 5.1 (snake_case lowercase) Nearby struct не получил
json-теги. /search/nearby возвращал {UserID, Name, Lat, ...}
а фронт ждал {user_id, name, lat, ...} — markers не рисовались.

Фикс: добавил json:"..." на все поля Nearby.
Проверено: snake_case теперь везде в /search/nearby.
2026-08-21 11:55:22 +00:00
ga
21c413a9cc Fix: search/nearby 500 (pgx numeric vs float8)
pgx по умолчанию передаёт float64 как numeric.
В запросе BETWEEN $1 - $6 AND $1 + $6 numeric-numeric
сравнивалось с double precision lat/lng и возвращало ошибку.

Фикс: ::float8 касты на все параметры запроса.
Проверено: /search/nearby → 200 с count=2 для юзеров в 600м.
2026-08-21 11:50:49 +00:00
ga
aafbc6f047 Backend: 'Запомнить меня' — remember=true ставит cookie на 30 дней (refresh TTL) 2026-08-21 11:19:00 +00:00
ga
2a765b5df5 Fix Safari: cookie SameSite=Lax (same-origin proxy работает) 2026-08-21 11:04:13 +00:00
ga
8cb0a066b8 Fix Safari login: Connection:close + SameSite=None (Grok analysis)
Safari блокирует fetch после POST с Set-Cookie из-за keep-alive/HTTP2.
- Login/Register: Connection: close, Cache-Control: no-store
- Cookie: SameSite=None (кросс-поддомен buhapp → api.buhapp)
2026-08-21 10:57:22 +00:00
ga
6e2a54820e Auth: POST /api/v1/auth/logout — чистит HttpOnly cookie 2026-08-20 22:13:20 +00:00
ga
0c1de393d2 Fix: updateMe — пустая строка gender = NULL (не указан)
Раньше пустая строка падала с 400 'gender must be m, f, o'
2026-08-20 22:09:08 +00:00
ga
5b70bc3137 Auth: HttpOnly cookie buhapp_at (без CORS preflight)
- Login/Register ставят cookie (HttpOnly, Secure, SameSite=Lax)
- Middleware читает cookie первым
- CORS: AllowCredentials=true
- Для прямых API-вызовов остался Authorization Bearer
- Legacy ?_t= query fallback
2026-08-20 21:50:28 +00:00
ga
249c3d2a8f Sprint 8.1: /api/v1/debug/log endpoint для клиентских логов 2026-08-20 21:38:27 +00:00
ga
748b4a31fb Sprint 8: 2GIS tiles + places (бары/рестораны) nearby
- internal/places/overpass.go: запрос к Overpass API (OSM), bar/pub/restaurant/cafe/biergarten/nightclub
- internal/handlers/places.go: GET /api/v1/places/nearby (radius, limit)
- POST через application/x-www-form-urlencoded (раньше был broken — query params)
- 2GIS tile layer в map.js (вместо OSM)
- Кнопка 'Показать/Скрыть бары' + список под картой
- Invite to place: шлёт предложение встретиться в чат с собеседником
- Карточки с эмодзи по типу заведения, расстояние, время работы
2026-08-20 21:11:54 +00:00
ga
0f9e0ce596 Sprint 7: race conditions + read_at + slog
1. chat.EnsureChat: ON CONFLICT DO UPDATE (race-safe)
2. chat.Send: tx.Begin/Commit (atomic INSERT message + UPDATE last_msg_at)
3. chat.MarkRead: добавил member-check (NOT a member -> 403)
4. chat.Message: +ReadAt field
5. migrations/0006: read_at column on messages
6. locations.Nearby: bounding-box prefilter + CTE (haversine только для отфильтрованных)
7. audit.Log: real metadata JSON passthrough (no more 'null' TODO)
8. main.go: slog JSON logger (был stdlib log)
9. WS: 'message_read' event от MarkRead
10. WS push: добавлены read/read_at/edited в message payload
11. Bumped v0.6.0
2026-08-20 21:04:56 +00:00
ga
2d3bdfb98f Sprint 6.1: photo upload (MinIO) + storage proxy
- POST /api/v1/me/photo (multipart, field 'photo')
- MinIO upload via storage.UploadAvatar (avatars/{userID}/{uuid}-{ts})
- /storage/* backend route reads from MinIO + serves with proper headers
- nginx unchanged: /storage/* proxied to backend like everything else
- Bumped to v0.5.0
2026-08-20 20:59:52 +00:00
ga
c30faf02ef Sprint 6: security hardening
1. CORS whitelist (was '*'): only buhapp.mygoodservice.ru, t.me, web.telegram.org
2. Rate limit on /auth/login (10/min/IP) and /auth/register (5/hour/IP)
3. TGHandler: removed unused JWTSecret, added WebhookSecret, real secret check
4. Login: constant-time bcrypt on user enumeration (dummy hash)
5. TgUsername saved in users (was lost)
6. User.IsVerified=true for Telegram users
7. Register: 409 instead of 500 on duplicate email
8. Bumped version to 0.4.0
2026-08-20 20:42:22 +00:00
ga
c6d219c51f Telegram WebApp support + consent endpoint
- Telegram bot (long polling)
- /api/v1/auth/telegram (validate initData, auto-create user)
- /api/v1/auth/consents (record acceptances)
- users.telegram_id column, GetByTelegramID/CreateWithTelegramID
- ValidateInitData (HMAC-SHA256 with WebAppData secret)
2026-08-20 17:43:20 +00:00
ga
778a2da4ef Sprint 5.1: JSON snake_case tags + lowercased fields
- All response types now use lowercase json tags (id, name, photo_url, etc.)
- email/phone/birthdate/last_seen_at/photo_url use omitempty
- audit.Metadata type []byte (was map[string]any)
- fixes register/login inconsistency where login returned ID/Name (CamelCase)
  while register returned id/name (lowercase)
2026-08-20 16:29:02 +00:00
ga
1eb7af6bac Sprint 5: reviews and ratings
- POST /api/v1/reviews (one per chat_id, UNIQUE)
- GET  /api/v1/users/:id/reviews (public list)
- GET  /api/v1/users/:id/stats (rating_avg, count)
- migration 0004: reviews (rating 1-5, anonymous flag), user_stats aggregate
- only chat participants can review; reviewed_id is other party
2026-08-20 16:20:15 +00:00
ga
3fe6930af2 Chat edit with WS notification
- PUT /messages/:msgId now returns {ok, edited:true}
- WS pushes 'message_edited' event to both chat members
- Mobile UI: show 'ред.' marker when edited=true
- Audit log: message.edit action
- Repo: GetMessage helper for fetching after edit
2026-08-20 15:52:57 +00:00
ga
4533ceaf2d Sprint 3: chat with WebSocket
- POST /api/v1/chats (ensure chat between users, normalized pair)
- GET  /api/v1/chats (list with last message + unread)
- GET  /api/v1/chats/:id/messages
- POST /api/v1/chats/:id/messages (send text/photo, push via WS)
- PUT  /api/v1/chats/:id/read (mark all read)
- PUT  /api/v1/messages/:msgId (edit, owner only)
- DELETE /api/v1/messages/:msgId (soft delete)
- POST /api/v1/blocks, DELETE /api/v1/blocks/:id
- POST /api/v1/reports
- WS   /ws?token= (real-time message push, ping/pong)
- migrations 0003: chats, messages, blocks, reports
2026-08-20 15:51:05 +00:00
ga
d4997e85ef Sprint 2: profile, preferences, location, search
- PUT  /api/v1/me (update name, city, bio, gender, photo)
- GET/PUT /api/v1/me/prefs (drinks, activities, purposes, language)
- PUT  /api/v1/me/location (auto-noise ~300m)
- PUT  /api/v1/me/visibility (hide/show on map)
- GET  /api/v1/search/nearby?lat&lng&radius (haversine, 1h TTL)
- GET  /api/v1/users/:id (public profile, no email/phone)
- migrations 0002: user_preferences, user_locations
2026-08-20 15:49:21 +00:00
ga
8d754f9834 Sprint 1: scaffold backend (Go + Fiber + PG + Redis + MinIO)
- POST /api/v1/auth/register with mandatory consents
- POST /api/v1/auth/login
- GET  /api/v1/me (protected)
- GET  /api/v1/legal/{terms,privacy,disclaimer}
- Migrations for users, consent_log, audit_log
- bcrypt + JWT (access + refresh)
- Docker Compose stack
2026-08-20 15:41:05 +00:00
ga
72a24ab492 Initial commit 2026-08-20 18:31:35 +03:00