67🥳
уже 68
снова 67
снова 68
Post #177
50
- ❤ 10
- ⚡ 3
VE @ventttp
This post (sticker, poll or similar) has no web preview. Open in Telegram
"!"sumweirdshrimps
Forwarded from "!"sumweirdshrimps
This post (sticker, poll or similar) has no web preview. Open in Telegram
This post (sticker, poll or similar) has no web preview. Open in Telegram
This post (sticker, poll or similar) has no web preview. Open in Telegram
This post (sticker, poll or similar) has no web preview. Open in Telegram
Forwarded from .vozderjus// (Vozderjus @)
./\ El camino nunca se detiene, solo olvida hacia dónde se dirigía, y tú lo olvidas junto con él. \].
// The path never stops, it only forgets where it was heading, and you forget right along with it.
Сотрудничество: @shotmeinmyeyes
This post (sticker, poll or similar) has no web preview. Open in Telegram
This post (sticker, poll or similar) has no web preview. Open in Telegram















Android — Compose, Material 3, MVVM, многомодульный Gradle (13 модулей), Coroutines/Flow, Hilt, Retrofit, свой STOMP-клиент на OkHttp, Room + Paging 3, DataStore, шифрованное хранилище токенов, FusedLocationProvider, Navigation Compose, кастомные Canvas-иллюстрации. Тесты — JUnit4, MockK, Turbine, Compose UI Test.
Бэкенд — Spring Boot 3, suspend-контроллеры, Spring Security с JWT, JPA, Spring Data MongoDB и Redis, Spring AMQP, WebSocket/STOMP, Thymeleaf, Flyway, springdoc-openapi. Тесты — JUnit 5, MockK, Testcontainers.
Инфраструктура PostgreSQL 16 + PostGIS, MongoDB 7, Redis 7, RabbitMQ с DLQ, MinIO, Docker Compose, GitHub Actions.
D1. PostgreSQL + MongoDB вместе. Из ТЗ: Postgres (+PostGIS) источник истины для всего транзакционного; MongoDB только conversations/messages.
D2. geometry(Point,4326) вместо geography в колонке. Hibernate Spatial валидирует geometry-тип без сюрпризов; метровая семантика достигается кастом ::geography в каждом гео-запросе (ST_DWithin, ST_Distance). Поведение идентично, схема дружит с ddl-auto: validate.
D3. EXIF-стрипинг через полный переэнкод. Вместо вырезания EXIF-тегов изображение декодируется и собирается заново (Thumbnailator → JPEG). Метаданные (включая GPS) исчезают by construction, а «полиглоты» (файлы с двойным дном) не переживают переэнкод. Принимаются только JPEG/PNG по magic bytes.
D4. Suspend-контроллеры + блокирующие сервисы. Spring MVC поддерживает suspend-хендлеры; JPA остаётся блокирующим, поэтому паттерн: suspend fun → withContext(Dispatchers.IO) { транзакционный сервис }. @Transactional на suspend-функциях с JPA не работает — транзакции живут только внутри блокирующего слоя.
D5. ASYNC-dispatch разрешён в Spring Security. Suspend-контроллеры завершаются через ASYNC-dispatch, где OncePerRequestFilter (JWT) по умолчанию не выполняется → AuthorizationFilter видел анонима и валил запрос 401-м. Решение из документации: dispatcherTypeMatchers(DispatcherType.ASYNC).permitAll() — аутентификация уже проверена на исходном REQUEST-dispatch.
D6. Установка SecurityContext — только через createEmptyContext() + setContext(). Мутация deferred-контекста (getContext().authentication = …) в Spring Security 6 теряется.
D7. Нормализация пары мэтча — лексикографически по uuid.toString(). UUID.compareTo в Java сравнивает знаково и НЕ совпадает с порядком uuid в PostgreSQL; строковое сравнение hex-представления совпадает с байтовым порядком БД, на котором держится CHECK-констрейнт user_a_id < user_b_id.
D8. Advisory-lock пары при свайпе. pg_advisory_xact_lock(hashtextextended(a:b)) сериализует встречные лайки — дубль мэтча невозможен даже при гонке.
Более тг не дает написать(((