module 3 lesson 1

This commit is contained in:
Александр Веденёв
2025-02-05 13:23:17 +07:00
parent 581435725a
commit f0446dee20
40 changed files with 5812 additions and 0 deletions

View File

@ -1 +1,78 @@
# otus-kotlin-developer
Учебный проект курса
[Kotlin Backend Developer](https://otus.ru/lessons/kotlin/).
Поток курса 2024-11.
**Messenger** — это программное обеспечение, предназначенное для обмена информацией между пользователями.
**Проблема существующих решений**
Главный недостаток современных мессенджеров — необходимость использовать отдельные приложения для рабочих и личных задач.
Корпоративные мессенджеры, как правило, не имеют встроенных инструментов тайм-менеджмента (например, планирования задач, контроля времени),
и их функционал расширяется только за счёт сторонних плагинов или интеграций.
**Цель разработки**
Программное обеспечение призвано объединить корпоративное и личное общение в единой платформе.
**Ключевые функции:**
- **Два режима работы:**
- Быстрое переключение между рабочим и личным режимами.
- Автоматическая сортировка контактов и чатов в зависимости от выбранного режима (например, отдельные группы для коллег и друзей).
- **Интеграция с инструментами планирования:**
- Синхронизация с общим календарём.
- Мгновенное создание встреч через подключённые сервисы (Google Meet, Zoom и другие видеоконференц-платформы) без перехода во внешние приложения.
- **Встроенный тайм-менеджмент:**
- Напоминания о задачах и встречах.
- Статистика времени, затраченного на рабочие/личные активности.
## Визуальная схема фронтенда
![Макет фронта](docs/imgs/design-layout.png)
## Документация
1. Маркетинг и аналитика
1. [Целевая аудитория](docs/01-biz/01-target-audience.md)
2. [Заинтересанты](docs/01-biz/02-stakeholders.md)
3. [Пользовательские истории](docs/01-biz/03-bizreq.md)
2. Аналитика:
1. [Функциональные требования](docs/02-analysis/01-functional-requiremens.md)
2. [Нефункциональные требования](docs/02-analysis/02-nonfunctional-requirements.md)
3. DevOps
1. [Файлы сборки](deploy)
4. Архитектура
1. [Описание API](docs/03-architecture/01-api.md)
2. [Компонентная схема](docs/03-architecture/02-arch.md)
5. Тесты
# Структура проекта
## Подпроекты для занятий по языку Kotlin
1. Модуль 1: Введение в Kotlin
1. [m1l1-first](ok-lessons/m1l1-first) - Вводное занятие, создание первой программы на Kotlin
2. [m1l2-basic](ok-lessons/m1l2-basic) - Основные конструкции Kotlin
3. [m1l3-func](ok-lessons/m1l3-func) - Функциональные элементы Kotlin
4. [m1l4-oop](ok-lessons/m1l4-oop) - Объектно-ориентированное программирование
2. Модуль 2: Расширенные возможности Kotlin
1. [m2l1-dsl](ok-lessons/m2l1-dsl) - Предметно ориентированные языки (DSL)
2. [m2l2-coroutines](ok-lessons/m2l2-coroutines) - Асинхронное и многопоточное программирование с корутинами
3. [m2l3-flows](ok-lessons/m2l3-flows) - Асинхронное и многопоточное программирование с Sequence и Flow
4. [m2l4-kmp](ok-lessons/m2l4-kmp) - Мультиплатформенная разработка
5. m2l5 - Интероперабельность Kotlin с другими языками
1. [m2l5-1-interop](ok-lessons/m2l5-1-interop) - Интероперабельность Kotlin Native с C
2. [m2l5-2-jni](ok-lessons/m2l5-2-jni) - Интероперабельность Kotlin JVM с C
6. [m2l6-gradle](ok-lessons/m2l6-gradle) - Расширенные возможности Gradle
## Проектные модули

19
deploy/Dockerfile Normal file
View File

@ -0,0 +1,19 @@
# Pull the minimal Ubuntu image
FROM ubuntu:22.04
# Install Nginx
RUN apt-get -y update && apt-get -y install nginx
#RUN useradd -ms /bin/bash mynginx
# Copy the Nginx config
COPY ./volumes/nginx/default.conf /etc/nginx/conf.d/
COPY ./volumes/nginx/nginx.conf /etc/nginx/
# Expose the port for access
EXPOSE 8080/tcp
# Не работает: nginx требует права root
#USER mynginx
# Run the Nginx server
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]

9
deploy/README.md Normal file
View File

@ -0,0 +1,9 @@
# deploy
## Настройка
Для корректного запуска файлов, необходимо добавить в настройки ядра Linux следующий параметр:
**/etc/sysctl.d/20-opensearch.conf:**
```
vm.max_map_count = 262144
```

14
deploy/call-envoy.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
#TOKEN=""
TOKEN=$(./keycloak-tokens.sh)
#curl -H "Authorization: Bearer ${TOKEN}" \
# -H "X-Request-ID: 1234" \
# -H "x-client-request-id: 1235" \
# http://localhost:8080/
curl -H "Authorization: Bearer ${TOKEN}" \
-H "X-Request-ID: 1234" \
-H "x-client-request-id: 1235" \
http://localhost:8080/v1/ad/

45
deploy/cert-gen.sh Executable file
View File

@ -0,0 +1,45 @@
#!/bin/bash
JKS_PASS=app123456
DIR_CA=volumes/ca
DIR_ENVOY=volumes/envoy/certs
DIR_KC=volumes/keycloak/certs
# Create directories
mkdir -p $DIR_CA
mkdir -p $DIR_ENVOY
mkdir -p $DIR_APP
mkdir -p $DIR_KC
# Generate CA private key
openssl genpkey -algorithm RSA -out $DIR_CA/ca.key
# Generate CA certificate
openssl req -x509 -new -nodes -key $DIR_CA/ca.key -sha256 -days 365 -out $DIR_CA/ca.crt -subj "/CN=my_ca"
# envoy certificates ----------------------------------------------------
# Generate envoy_sidecar private key
openssl genpkey -algorithm RSA -out $DIR_ENVOY/envoy_sidecar.key
# Generate a certificate signing request (CSR) for envoy_sidecar
openssl req -new -key $DIR_ENVOY/envoy_sidecar.key -out $DIR_ENVOY/envoy_sidecar.csr -subj "/CN=envoy_sidecar"
# Sign the CSR with the CA to get the envoy_sidecar certificate
openssl x509 -req -in $DIR_ENVOY/envoy_sidecar.csr -CA $DIR_CA/ca.crt -CAkey $DIR_CA/ca.key -CAcreateserial -out $DIR_ENVOY/envoy_sidecar.crt -days 365 -sha256
# keycloack certificates ----------------------------------------------------
# Generate Keycloak private key and certificate
openssl genpkey -algorithm RSA -out $DIR_KC/keycloak.key
openssl req -new -key $DIR_KC/keycloak.key -out $DIR_KC/keycloak.csr -subj "/CN=keycloak"
openssl x509 -req -in $DIR_KC/keycloak.csr -CA $DIR_CA/ca.crt -CAkey $DIR_CA/ca.key -CAcreateserial -out $DIR_KC/keycloak.crt -days 365 -sha256
# Convert Keycloak certificates to PKCS12 format
openssl pkcs12 -export -out $DIR_KC/keycloak.p12 -inkey $DIR_KC/keycloak.key -in $DIR_KC/keycloak.crt -name keycloak -passout pass:$JKS_PASS
# Convert PKCS12 to JKS
keytool -importkeystore -srckeystore $DIR_KC/keycloak.p12 -srcstoretype pkcs12 -destkeystore $DIR_KC/keycloak.jks -deststoretype JKS -srcstorepass $JKS_PASS -deststorepass $JKS_PASS
echo "Certificates generated successfully!"

View File

@ -0,0 +1,100 @@
# Кластерная версия инфраструктуры на базе
# OpenSearch (2 узла)
# OpenSearch Dashboards
# Fluent Bit
version: '3'
services:
app:
image: nginx:latest
ports:
- "8080:80"
depends_on:
- fluent-bit
volumes:
- ./volumes/nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./volumes/nginx/nginx.conf:/etc/nginx/nginx.conf
logging:
# используемый драйвер логгирования
driver: "fluentd"
options:
# куда посылать лог-сообщения, необходимо чтобы адрес
# совпадал с настройками плагина forward
fluentd-address: localhost:24224
# теги используются для маршрутизации лог-сообщений, тема
# маршрутизации будет рассмотрена ниже
tag: app.logs
fluent-bit:
container_name: fluent-bit
image: fluent/fluent-bit
ports:
# необходимо открыть порты, которые используются плагином forward
- "24224:24224"
- "24224:24224/udp"
- "2020:2020"
environment:
- opensearch_host=opensearch
- opensearch_user=admin
- opensearch_pass=admin
volumes:
- ./volumes/fluent-bit-etc/fluent-bit.conf:/fluent-bit/etc/fluent-bit.conf
- ./volumes/fluent-bit-etc/parsers.conf:/fluent-bit/etc/parsers.conf
opensearch:
image: opensearchproject/opensearch:latest
environment:
- cluster.name=opensearch-cluster # Name the cluster
- node.name=opensearch # Name the node that will run in this container
- discovery.seed_hosts=opensearch,opensearch2 # Nodes to look for when discovering the cluster
- cluster.initial_cluster_manager_nodes=opensearch,opensearch2 # Nodes eligible to serve as cluster manager
- bootstrap.memory_lock=true
- ES_JAVA_OPTS=-Xms512m -Xmx512m
ports:
- '9200:9200'
- '9600:9600'
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- opensearch-data1:/usr/share/opensearch/data
opensearch2:
image: opensearchproject/opensearch:latest
environment:
- cluster.name=opensearch-cluster
- node.name=opensearch2
- discovery.seed_hosts=opensearch,opensearch2
- cluster.initial_cluster_manager_nodes=opensearch,opensearch2
- bootstrap.memory_lock=true
- ES_JAVA_OPTS=-Xms512m -Xmx512m
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- opensearch-data2:/usr/share/opensearch/data
dashboards:
image: opensearchproject/opensearch-dashboards:latest
container_name: opensearch-dashboards
ports:
- 5601:5601
expose:
- "5601"
environment:
OPENSEARCH_HOSTS: '["https://opensearch:9200","https://opensearch2:9200"]'
depends_on:
- opensearch
volumes:
opensearch-data1:
opensearch-data2:

View File

@ -0,0 +1,79 @@
# Минимальная версия инфраструктуры на базе
# OpenSearch
# OpenSearch Dashboards
# Fluent Bit
version: '3'
services:
app:
image: nginx:latest
ports:
- "8080:80"
depends_on:
- fluent-bit
volumes:
- ./volumes/nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./volumes/nginx/nginx.conf:/etc/nginx/nginx.conf
logging:
# используемый драйвер логгирования
driver: "fluentd"
options:
# куда посылать лог-сообщения, необходимо чтобы адрес
# совпадал с настройками плагина forward
fluentd-address: localhost:24224
# теги используются для маршрутизации лог-сообщений, тема
# маршрутизации будет рассмотрена ниже
tag: app.logs
fluent-bit:
container_name: fluent-bit
image: fluent/fluent-bit
ports:
# необходимо открыть порты, которые используются плагином forward
- "24224:24224"
- "24224:24224/udp"
- "2020:2020"
environment:
- opensearch_host=opensearch
- opensearch_user=admin
- opensearch_pass=admin
volumes:
- ./volumes/fluent-bit-etc/fluent-bit.conf:/fluent-bit/etc/fluent-bit.conf
- ./volumes/fluent-bit-etc/parsers.conf:/fluent-bit/etc/parsers.conf
opensearch:
container_name: opensearch
image: opensearchproject/opensearch:latest
environment:
- discovery.type=single-node
- http.port=9200
- bootstrap.memory_lock=true
- ES_JAVA_OPTS=-Xms512m -Xmx512m
ports:
- '9200:9200'
- '9600:9600'
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- opensearch-data:/usr/share/opensearch/data
dashboards:
image: opensearchproject/opensearch-dashboards:latest
container_name: opensearch-dashboards
ports:
- 5601:5601
expose:
- "5601"
environment:
OPENSEARCH_HOSTS: '["https://opensearch:9200"]'
depends_on:
- opensearch
volumes:
opensearch-data:

View File

@ -0,0 +1,92 @@
# Минимальная версия инфраструктуры на базе
# OpenSearch
# OpenSearch Dashboards
# Kafka
# Logstash
version: '3'
services:
app:
image: bitnami/kafka:latest
depends_on:
- kafka
volumes:
- ./volumes/app-kafka/send-jsons.sh:/send-jsons.sh
entrypoint: /send-jsons.sh
zookeeper:
image: 'bitnami/zookeeper:latest'
ports:
- '2181:2181'
environment:
- ALLOW_ANONYMOUS_LOGIN=yes
kafka:
image: bitnami/kafka:latest
ports:
- '9092:9092'
environment:
# Во внутренней сети docker-compose слушаем адрес kafka:9092
# Из внешней сети docker-compose будем слушать localhost:9094
# Как альтерантива, можно вычислять адрес как-то так:
# HOSTNAME_COMMAND: curl http://169.254.169.254/latest/meta-data/public-hostname
- KAFKA_BROKER_ID=1
- KAFKA_CFG_LISTENERS=PLAINTEXT://0.0.0.0:9092,OUTSIDE://0.0.0.0:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,OUTSIDE://localhost:9094
- KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,OUTSIDE:PLAINTEXT
- KAFKA_CFG_INTER_BROKER_LISTENER_NAME=PLAINTEXT
- ALLOW_PLAINTEXT_LISTENER=yes
logstash:
container_name: logstash
image: opensearchproject/logstash-oss-with-opensearch-output-plugin:latest
depends_on:
- kafka
- opensearch
ports:
- "5044:5044"
- "1111:1111"
environment:
BOOTSTRAP_SERVERS: "kafka:9092"
volumes:
# - ./volumes/logstash/logstash.yml:/usr/share/logstash/config/logstash.yml
- ./volumes/logstash/10-mp-logs.conf:/usr/share/logstash/pipeline/10-mp-logs.conf
opensearch:
container_name: opensearch
image: opensearchproject/opensearch:latest
environment:
- discovery.type=single-node
- http.port=9200
- bootstrap.memory_lock=true
- ES_JAVA_OPTS=-Xms512m -Xmx512m
ports:
- '9200:9200'
- '9600:9600'
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- opensearch-data:/usr/share/opensearch/data
dashboards:
image: opensearchproject/opensearch-dashboards:latest
container_name: opensearch-dashboards
ports:
- 5601:5601
expose:
- "5601"
environment:
OPENSEARCH_HOSTS: '["https://opensearch:9200"]'
depends_on:
- opensearch
volumes:
opensearch-data:

141
deploy/docker-compose.yml Normal file
View File

@ -0,0 +1,141 @@
# Минимальная версия инфраструктуры на базе
# OpenSearch - хранилище логов и метрик
# OpenSearch Dashboards - отрисовка логов
# Fluent Bit - служба сбора логов
# Envoy - прокси
# Keycloak - сервер идентификации
# Адреса:
# Приложение доступно по http://localhost:8080 (envoy прокси)
# Панели мониторинга http://localhost:5601 (opensearch dashboards, kibana)
# Управление пользователями http://localhost:8080/admin (keycloak)
services:
app:
image: nginx:latest
depends_on:
- fluent-bit
- envoy
volumes:
- ./volumes/nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./volumes/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./volumes/nginx/html:/usr/share/nginx/html
logging:
# используемый драйвер логгирования
driver: "fluentd"
options:
# куда посылать лог-сообщения, необходимо чтобы адрес
# совпадал с настройками плагина forward
fluentd-address: localhost:24224
# теги используются для маршрутизации лог-сообщений, тема
# маршрутизации будет рассмотрена ниже
tag: app.logs
fluent-bit:
# Logstash: 2GB RAM 400MB Docker
# fluent-bit: 30MB Docker 30MB RAM
container_name: fluent-bit
image: fluent/fluent-bit
ports:
# необходимо открыть порты, которые используются плагином forward
- "24224:24224"
- "24224:24224/udp"
- "2020:2020"
environment:
- opensearch_host=opensearch
- opensearch_user=admin
- opensearch_pass=adm-Password0
volumes:
- ./volumes/fluent-bit-etc/fluent-bit.conf:/fluent-bit/etc/fluent-bit.conf
- ./volumes/fluent-bit-etc/parsers.conf:/fluent-bit/etc/parsers.conf
opensearch:
container_name: opensearch
image: opensearchproject/opensearch:latest
environment:
- discovery.type=single-node
- http.port=9200
- bootstrap.memory_lock=true
- ES_JAVA_OPTS=-Xms512m -Xmx512m
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=adm-Password0
ports:
- '9200:9200'
- '9600:9600'
healthcheck:
test:
[
"CMD-SHELL",
"curl -ku admin:adm-Password0 https://localhost:9200/_cluster/health?pretty | grep status | grep -q '\\(green\\|yellow\\)'"
]
interval: 5s
timeout: 5s
retries: 24
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
# volumes:
# - opensearch-data:/usr/share/opensearch/data
dashboards:
image: opensearchproject/opensearch-dashboards:latest
container_name: opensearch-dashboards
ports:
- 5601:5601
expose:
- "5601"
environment:
OPENSEARCH_HOSTS: '["https://opensearch:9200"]'
depends_on:
opensearch:
condition: service_healthy
envoy:
image: envoyproxy/envoy:v1.29.0 # Use the official Envoy proxy image
volumes:
- ./volumes/envoy/envoy.yaml:/etc/envoy/envoy.yaml # Mount your Envoy configuration file
# - ./envoy/certs:/etc/envoy/certs # Mount your TLS certificates
ports:
- "8080:8080"
depends_on:
keycloak:
condition: service_healthy
keycloak:
image: quay.io/keycloak/keycloak:26.1.0
# ports:
# - "8081:8080"
volumes:
- ./volumes/keycloak/import:/opt/keycloak/data/import
# - ./keycloak/standalone.xml:/opt/jboss/keycloak/standalone/configuration/standalone.xml
# - ./keycloak/certs/keycloak.jks:/etc/x509/https/keystore # Mount your Keycloak keystore
environment:
KEYCLOAK_USER: otus
KEYCLOAK_PASSWORD: otus
KC_BOOTSTRAP_ADMIN_USERNAME: admin
KC_BOOTSTRAP_ADMIN_PASSWORD: admin
KEYCLOAK_IMPORT: "/tmp/realm-export.json"
KC_HEALTH_ENABLED: "true"
healthcheck:
test: [ "CMD-SHELL", "exec 3<>/dev/tcp/127.0.0.1/9000;echo -e 'HEAD /health/ready HTTP/1.1\r\nHost: localhost:9000\r\nConnection: close\r\n\r\n' >&3;cat <&3"]
interval: 10s
timeout: 5s
retries: 15
command:
- start-dev
- --import-realm
- --hostname-strict
- "false"
- --hostname
- "http://localhost:8080/"
- --proxy-headers
- forwarded
- --hostname-backchannel-dynamic
- "true"
volumes:
opensearch-data:

22
deploy/keycloak-tokens.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/bash
KCHOST=http://localhost:8080
REALM=otus-marketplace
CLIENT_ID=otus-marketplace-service
UNAME=otus-test
PASSWORD=otus
# shellcheck disable=SC2006
#ACCESS_TOKEN=`curl \
# -d "client_id=$CLIENT_ID" -d "client_secret=$CLIENT_SECRET" \
# -d "username=$UNAME" -d "password=$PASSWORD" \
# -d "grant_type=password" \
# "$KCHOST/auth/realms/$REALM/protocol/openid-connect/token" | jq -r '.access_token'`
ACCESS_TOKEN=`curl \
-d "client_id=$CLIENT_ID" \
-d "username=$UNAME" \
-d "password=$PASSWORD" \
-d "grant_type=password" \
"$KCHOST/realms/$REALM/protocol/openid-connect/token" | jq -r '.access_token'`
echo "$ACCESS_TOKEN"

2
deploy/volumes/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*/certs/
/ca/

View File

@ -0,0 +1,17 @@
#!/bin/bash
export LC_ALL=C
TOPIC=ok-mkpl-logs
/opt/bitnami/kafka/bin/kafka-topics.sh \
--bootstrap-server kafka:9092 \
--topic $TOPIC --create --partitions 3 --replication-factor 1
while true
do
TIME=$(date +"%Y-%m-%dT%H:%M:%S.%N%z")
echo "{\"@timestamp\":\"$TIME\",\"log\":\"ok\"}" | \
/opt/bitnami/kafka/bin/kafka-console-producer.sh --bootstrap-server kafka:9092 --topic $TOPIC \
&& echo "sent at $TIME"
sleep 10
done

View File

@ -0,0 +1,92 @@
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address:
address: 0.0.0.0
port_value: 15001
static_resources:
listeners:
- name: listener_app
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: [ "*" ]
routes:
- match: { path: "/" }
route: { cluster: app }
- match: { prefix: "/v1/ad/" }
route: { cluster: app }
- match: { prefix: "/v2/ad/" }
route: { cluster: app }
- match: { prefix: "/admin/" }
route: { cluster: keycloak }
- match: { prefix: "/realms/" }
route: { cluster: keycloak }
- match: { prefix: "/resources/" }
route: { cluster: keycloak }
http_filters:
- name: envoy.filters.http.jwt_authn
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
providers:
keycloak_provider:
issuer: "http://localhost:8080/realms/otus-marketplace"
remote_jwks:
http_uri:
uri: http://keycloak:8080/realms/otus-marketplace/protocol/openid-connect/certs
cluster: keycloak
timeout: 5s
cache_duration:
seconds: 300
# Пробрасываем JWT в заголовок запроса
forward: true
forward_payload_header: x-jwt-payload
rules:
- match: { prefix: /v1/ad/ }
requires: { provider_name: keycloak_provider }
- match: { prefix: /v2/ad/ }
requires: { provider_name: keycloak_provider }
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: app
connect_timeout: 30s
type: LOGICAL_DNS
dns_lookup_family: V4_ONLY
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: app
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: app
port_value: 8080
- name: keycloak
connect_timeout: 0.25s
type: LOGICAL_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: keycloak
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: keycloak
port_value: 8080

View File

@ -0,0 +1,70 @@
[SERVICE]
log_level info
flush 1
HTTP_Server On
HTTP_Listen 0.0.0.0
HTTP_PORT 2020
Health_Check On
Parsers_File parsers.conf
# App Logs --------------------------------------------------
[INPUT]
Name forward
# Name tcp
Tag app.logs
Listen 0.0.0.0
Port 24224
[FILTER]
Name parser
Match app.*
Key_Name message
Parser json
Reserve_Data True
[OUTPUT]
Name opensearch
Match app.*
Port 9200
Host ${opensearch_host}
HTTP_User ${opensearch_user}
HTTP_Passwd ${opensearch_pass}
Include_Tag_Key On
Logstash_Format On
Logstash_Prefix app-logs
Logstash_DateFormat %Y.%m.%d
Retry_Limit 2
Suppress_Type_Name On
tls On
tls.verify Off
Trace_Error On
net.keepalive On
Buffer_Size 25M
# CPU Usage --------------------------------------------------
[INPUT]
Name cpu
Tag cpu.load
[OUTPUT]
Name opensearch
Match cpu.load
Port 9200
Host ${opensearch_host}
HTTP_User ${opensearch_user}
HTTP_Passwd ${opensearch_pass}
Logstash_Format On
Logstash_Prefix cpu-load
Logstash_DateFormat %Y.%m.%d
Retry_Limit False
Suppress_Type_Name On
tls On
tls.verify Off
# [OUTPUT]
# Name stdout
# Match cpu.load
# Format json_stream
# json_date_key @timestamp
# json_date_format iso8601
#

View File

@ -0,0 +1,12 @@
[PARSER]
Name nginx_parser
Format regex
Regex ^access_log (?<remote_address>[^ ]*) "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<status>[^ ]*) "(?<http_user_agent>[^\"]*)"$
Types status:integer
[PARSER]
Name json
Format json
Time_Key @timestamp
Time_Format %Y-%m-%dT%H:%M:%S.%L%z
#Time_Keep On

3
deploy/volumes/keycloak/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/hsperfdata_*/
/certs/
/vertx-cache/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,24 @@
{
"realm" : "otus-marketplace",
"users" : [ {
"id" : "638647df-d9e4-4759-8748-6f99ac220d11",
"createdTimestamp" : 1706964619142,
"username" : "otus-test",
"enabled" : true,
"totp" : false,
"emailVerified" : true,
"credentials" : [ {
"id" : "56beee96-cf26-4f6e-83db-8138530e0148",
"type" : "password",
"userLabel" : "My password",
"createdDate" : 1706964634548,
"secretData" : "{\"value\":\"CBy36ufg5bdAyXTLX9gMYyxw4QXKiAkNox6NFYi8FuQ=\",\"salt\":\"wasUxUctTzzm0c5HTyy7Sw==\",\"additionalParameters\":{}}",
"credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
} ],
"disableableCredentialTypes" : [ ],
"requiredActions" : [ ],
"realmRoles" : [ "default-roles-otus-marketplace" ],
"notBefore" : 0,
"groups" : [ "/USER" ]
} ]
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,12 @@
<server xmlns="urn:jboss:domain:10.0">
<!-- other configurations -->
<subsystem xmlns="urn:jboss:domain:undertow:10.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
<https-listener name="https" socket-binding="https" security-realm="UndertowRealm" enable-http2="true">
<ssl>
<keystore path="/etc/x509/https/keystore" relative-to="jboss.server.config.dir" keystore-password="app123456" />
</ssl>
</https-listener>
<!-- other configurations -->
</subsystem>
<!-- other configurations -->
</server>

View File

@ -0,0 +1,29 @@
input {
kafka {
bootstrap_servers => "${BOOTSTRAP_SERVERS}"
topics => "ok-mkpl-logs"
codec => "json"
}
}
filter {
if [type] == "nginx" {
mutate {
add_field => [ "habra_field", "Hello Habr" ]
}
}
}
output {
opensearch {
id => "es_out_sensor_plugin_id"
hosts => ["https://opensearch:9200"]
user => "admin"
password => "admin"
ssl => true
ssl_certificate_verification => false
# Data streams only support create action
# action => "create"
index => "logs-marketplace-%{+YYYYMMdd}"
}
}

View File

@ -0,0 +1,3 @@
http.host: "0.0.0.0"
xpack.monitoring.elasticsearch.hosts: [ "http://elasticsearch:9200" ]
#xpack.monitoring.enabled: true

View File

@ -0,0 +1,27 @@
server {
listen 8080;
listen [::]:8080;
server_name localhost;
# access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /status {
stub_status;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

View File

@ -0,0 +1,8 @@
<html>
<head>
<title>Root</title>
</head>
<body>
<h1>Root</h1>
</body>
</html>

View File

@ -0,0 +1,8 @@
<html>
<head>
<title>V1 Ad</title>
</head>
<body>
<h1>V1 Ad</h1>
</body>
</html>

View File

@ -0,0 +1,8 @@
<html>
<head>
<title>V2 Ad</title>
</head>
<body>
<h1>V2 Ad</h1>
</body>
</html>

View File

@ -0,0 +1,34 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
log_format main 'access_log $remote_addr "$request" '
'$status "$http_user_agent"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}

40
docs/00-project-stages.md Normal file
View File

@ -0,0 +1,40 @@
# Этапы проекта
## 1. Инициация:
- **Описание:** На этом этапе проект определяется на общем уровне. Определяются начальные ресурсы, бюджет и общие цели.
- **Основные действия:**
- Определение проекта и концепции
- Идентификация заинтересованных сторон
- Разработка начального делового случая
## 2. Планирование:
- **Описание:** Проводится детальное планирование для определения четких целей, объема работ, сроков, ресурсов и бюджета.
- **Основные действия:**
- Создание подробного плана проекта
- Распределение ресурсов
- Оценка рисков и планирование их управления
- План коммуникации с заинтересованными сторонами
## 3. Выполнение:
- **Описание:** План проекта воплощается в жизнь, и выполняются работы для достижения целей проекта.
- **Основные действия:**
- Коллаборация команды и выполнение задач
- Регулярное обновление статуса и отчетность
- Постоянный мониторинг и контроль
- Вовлечение заинтересованных сторон
## 4. Мониторинг и контроль:
- **Описание:** Постоянное измерение активностей проекта и управление рисками для обеспечения достижения целей.
- **Основные действия:**
- Измерение производительности
- Контроль качества
- Разрешение проблем
- Управление изменениями в объеме работ
## 5. Завершение:
- **Описание:** Завершение всех активностей проекта, завершение выполнения задач и закрытие проекта.
- **Основные действия:**
- Формальное принятие результатов
- Передача результатов проекта заинтересованным сторонам
- Документация извлеченных уроков
- Отчет о завершении проекта

View File

@ -0,0 +1,74 @@
# Целевая аудитория
## Основные клиенты:
1. **ИТ-компании и стартапы**
* Размер: От небольших команд (510 человек) до крупных компаний (100+ сотрудников).
* Сфера: Разработка ПО, SaaS-платформы, кибербезопасность, облачные сервисы.
2. **Фрилансеры и удаленные работники**
* Профессии: Разработчики, дизайнеры, копирайтеры, менеджеры проектов.
* География: Международная аудитория (Россия, СНГ, Европа, США).
## Гипотетические портреты клиентов
1. **Менеджер проектов в ИТ-компании**
**Демография:**
* Женщина/мужчина 2845 лет.
* Высшее образование (менеджмент, компьютерные науки).
* Опыт: 3+ года в управлении agile-командами.
**Психологический портрет:**
* Организатор: Ценит структурированность и автоматизацию процессов.
* Прагматик: Выбирает инструменты с интеграцией в текущий стек (Jira, Trello, GitHub).
**Контекст использования:**
* Координация задач между разработчиками, дизайнерами и заказчиками.
* Создание встреч для спринт-планирования и ретроспектив.
**Боль:**
* Фрагментация коммуникации (Slack для чатов, Zoom для звонков, отдельный календарь).
* Сложности с разделением рабочих и личных уведомлений.
2. **Фрилансер-разработчик**
**Демография:**
* Мужчина/женщина 2235 лет.
* Самообразование или курсы (без классического диплома).
* Работает на Upwork, Fiverr, Toptal.
**Контекст использования:**
* Параллельно ведет 35 проектов.
* Использует личный мессенджер для общения с клиентами.
**Боль:**
* Путаница между личными сообщениями и рабочими чатами.
* Нет инструментов для быстрого создания встреч (приходится вручную генерировать ссылки в Zoom).
3. **Технический директор стартапа**
**Демография:**
* Мужчина/женщина 3050 лет.
* Техническое образование (Computer Science, Data Science).
* Опыт: 5+ лет в управлении разработкой.
**Контекст использования:**
* Минимизировать переключение между инструментами.
* Контролировать прогресс команды без микроменеджмента.
**Боль:**
* Отсутствие единого пространства для code review, обсуждения задач и планирования.
* Риски утечки данных через личные аккаунты сотрудников.

View File

@ -0,0 +1,85 @@
### Стейкхолдеры:
1. **Партнёры по интеграции (Zoom, Google Meet, Jira и др.)**
- *Описание:* Компании, предоставляющие API и сервисы для интеграции с мессенджером (видеозвонки, календари, трекеры задач).
- *Роли и обязанности:*
- Обеспечение стабильной работы API.
- Совместная разработка функций интеграции (например, создание встреч в один клик).
- Техническая поддержка при возникновении сбоев.
2. **ИТ-компании и стартапы**
- *Описание:* Организации, использующие мессенджер для внутренней и внешней коммуникации.
- *Роли и обязанности:*
- Внедрение мессенджера в рабочие процессы.
- Обратная связь по улучшению функционала (например, интеграция с GitHub).
- Тестирование корпоративных функций (рабочие режимы, безопасность).
3. **Конечные пользователи (фрилансеры, менеджеры, разработчики)**
- *Описание:* Физические лица, использующие мессенджер для личного и профессионального общения.
- *Роли и обязанности:*
- Активное использование функций (чаты, видеозвонки, календарь).
- Формирование запросов на новые возможности (например, шаблоны сообщений).
- Участие в опросах и бета-тестировании.
4. **Команда технической поддержки**
- *Описание:* Специалисты, обеспечивающие помощь пользователям и решение технических проблем.
- *Роли и обязанности:*
- Консультирование по настройке режимов и интеграций.
- Сбор багрепортов и их передача разработчикам.
- Обновление FAQ и базы знаний.
5. **DevOps-инженеры и сетевые администраторы**
- *Описание:* Специалисты, отвечающие за инфраструктуру и бесперебойную работу сервиса.
- *Роли и обязанности:*
- Мониторинг нагрузки на сервера.
- Оптимизация скорости доставки сообщений.
- Обеспечение отказоустойчивости и резервного копирования.
6. **Разработчики мессенджера**
- *Описание:* Команда, занимающаяся созданием и обновлением функционала приложения.
- *Роли и обязанности:*
- Реализация новых функций (например, разделение чатов по режимам).
- Исправление ошибок и улучшение UX/UI.
- Интеграция с внешними API (Google Calendar, Zoom).
7. **Маркетинговая команда**
- *Описание:* Специалисты, продвигающие мессенджер среди целевой аудитории.
- *Роли и обязанности:*
- Разработка рекламных кампаний для ИТ-сегмента и фрилансеров.
- Анализ конкуренции (Slack, Telegram, Discord).
- Продвижение через вебинары, кейсы и партнёрские программы.
8. **Юристы и специалисты по compliance**
- *Описание:* Эксперты, обеспечивающие соответствие законодательству (GDPR, защита данных).
- *Роли и обязанности:*
- Составление пользовательского соглашения и политики конфиденциальности.
- Контроль за шифрованием данных и правами доступа.
- Урегулирование споров, связанных с утечкой информации.
9. **Финансовый отдел**
- *Описание:* Сотрудники, управляющие бюджетом и монетизацией мессенджера.
- *Роли и обязанности:*
- Расчёт стоимости подписок (премиум-функции для корпораций).
- Анализ рентабельности интеграций с платными сервисами.
- Планирование расходов на хостинг и масштабирование.
10. **Владелец продукта**
- *Описание:* Лицо, отвечающее за стратегию развития мессенджера.
- *Роли и обязанности:*
- Приоритизация задач для команды (например, сначала MVP, потом аналитика).
- Коммуникация с инвесторами и партнёрами.
- Утверждение roadmap и финальных версий функций.
11. **Инвесторы и венчурные фонды**
- *Описание:* Лица/организации, финансирующие разработку и продвижение мессенджера.
- *Роли и обязанности:*
- Контроль выполнения KPI (например, количество активных пользователей).
- Участие в принятии решений о монетизации.
- Поиск стратегических партнёров для масштабирования.
---
### Дополнения и уточнения:
- Для **ИТ-компаний** критична интеграция с их текущим стеком инструментов (например, Jira для трекинга задач).
- **Фрилансеры** требуют простоты разделения личных/рабочих чатов и трекера времени.
- **Инвесторы** заинтересованы в быстром выходе на рынок B2B-сегмента (корпоративные подписки).

95
docs/01-biz/03-bizreq.md Normal file
View File

@ -0,0 +1,95 @@
### Пользовательские истории для DualSpace Messenger:
---
**User Story 1**
**Как** менеджер проектов,
**Я хочу** создавать Zoom-встречи прямо из чата с коллегами,
**Для того, чтобы** не тратить время на ручной ввод ссылок в календарь.
---
**User Story 2**
**Как** фрилансер-разработчик,
**Я хочу** переключаться между рабочим и личным режимами в один клик,
**Для того, чтобы** не путать чаты с коллегами и личные переписки.
---
**User Story 3**
**Как** технический директор стартапа,
**Я хочу** видеть статистику активности команды (время в рабочих чатах, выполнение задач),
**Для того, чтобы** оценивать продуктивность без микроменеджмента.
---
**User Story 4**
**Как** HR-менеджер,
**Я хочу** интегрировать мессенджер с корпоративным календарём,
**Для того, чтобы** автоматически синхронизировать собеседования и митапы.
---
**User Story 5**
**Как** администратор компании,
**Я хочу** управлять доступом сотрудников к рабочим чатам,
**Для того, чтобы** новые участники не видели архивные обсуждения.
---
**User Story 6**
**Как** дизайнер-фрилансер,
**Я хочу** прикреплять файлы из Figma к сообщениям,
**Для того, чтобы** клиенты сразу видели актуальные правки.
---
**User Story 7**
**Как** пользователь с повышенными требованиями к безопасности,
**Я хочу** включать сквозное шифрование для выбранных чатов,
**Для того, чтобы** защитить конфиденциальные переговоры.
---
**User Story 8**
**Как** менеджер по продажам,
**Я хочу** использовать шаблоны ответов для частых запросов,
**Для того, чтобы** ускорить коммуникацию с клиентами.
---
**User Story 9**
**Как** мобильный пользователь,
**Я хочу** получать push-уведомления только из рабочих чатов в нерабочие часы,
**Для того, чтобы** отделять срочные задачи от личных сообщений.
---
**User Story 10**
**Как** владелец ИТ-стартапа,
**Я хочу** видеть сводку по времени, затраченному командой на обсуждения,
**Для того, чтобы** оптимизировать совещательную нагрузку.
---
**User Story 11**
**Как** новичок в команде,
**Я хочу** быстро находить ключевые решения в истории чата по хештегам,
**Для того, чтобы** не задавать повторяющиеся вопросы коллегам.
---
**User Story 12**
**Как** пользователь с несколькими устройствами,
**Я хочу** синхронизировать статус "Не беспокоить" между телефоном и десктопом,
**Для того, чтобы** не пропускать важные уведомления при переключении устройств.
---
### Критерии приемки (пример для User Story 2):
1. В интерфейсе чата есть кнопка "Создать встречу".
2. При нажатии открывается выбор сервиса (Zoom/Google Meet).
3. Ссылка на конференцию генерируется автоматически и отправляется всем участникам чата.
4. Встреча добавляется в календарь пользователя и привязанных сервисов.
---

114
docs/01-documents-list.md Normal file
View File

@ -0,0 +1,114 @@
# Документы проекта
## 1. Инициация:
- **Бизнес-план (Business Plan)**
- *Описание:* Документ, описывающий бизнес-модель, стратегию, маркетинговые планы и прогнозы.
- *Ответственный стейкхолдер:* Владелец проекта.
- *Стейкхолдер, отвечающий за приемку:* Инвестор.
- *Стадия разработки:* Первоначальная стадия планирования проекта.
- **Техническое задание (Technical Specification)**
- *Описание:* Документ, определяющий технические требования к проекту.
- *Ответственный стейкхолдер:* Технический архитектор.
- *Стейкхолдер, отвечающий за приемку:* Владелец проекта.
- *Стадия разработки:* Первоначальная стадия планирования проекта.
## 2. Планирование:
- **План проекта (Project Plan)**
- *Описание:* Документ, определяющий цели, задачи, ресурсы и сроки проекта.
- *Ответственный стейкхолдер:* Менеджер проекта.
- *Стейкхолдер, отвечающий за приемку:* Стейкхолдеры проекта.
- *Стадия разработки:* Подготовительная стадия перед началом проекта.
- **Распределение ресурсов (Resource Allocation Plan)**
- *Описание:* Документ, определяющий распределение ресурсов для выполнения проекта.
- *Ответственный стейкхолдер:* Менеджер проекта.
- *Стейкхолдер, отвечающий за приемку:* Стейкхолдеры проекта.
- *Стадия разработки:* Подготовительная стадия перед началом проекта.
- **План управления рисками (Risk Management Plan)**
- *Описание:* Документ, определяющий стратегии по управлению рисками проекта.
- *Ответственный стейкхолдер:* Руководитель по управлению рисками.
- *Стейкхолдер, отвечающий за приемку:* Менеджер проекта.
- *Стадия разработки:* Подготовительная стадия перед началом проекта.
- **План коммуникации (Communication Plan)**
- *Описание:* Документ, определяющий стратегии и методы коммуникации внутри команды проекта и с заинтересованными
сторонами.
- *Ответственный стейкхолдер:* Менеджер проекта.
- *Стейкхолдер, отвечающий за приемку:* Стейкхолдеры проекта.
- *Стадия разработки:* Подготовительная стадия перед началом проекта.
## 3. Выполнение:
- **Протоколы совещаний (Meeting Minutes)**
- *Описание:* Документация ключевых моментов и решений, принятых на совещаниях по проекту.
- *Ответственный стейкхолдер:* Секретарь совещания.
- *Стейкхолдер, отвечающий за приемку:* Менеджер проекта.
- *Стадия разработки:* Фаза выполнения проекта.
- **Отчеты о статусе выполнения работ (Progress Reports)**
- *Описание:* Документация о текущем состоянии проекта, прогрессе и задачах.
- *Ответственный стейкхолдер:* Менеджер проекта.
- *Стейкхолдер, отвечающий за приемку:* Стейкхолдеры проекта.
- *Стадия разработки:* Фаза выполнения проекта.
- **Изменения в проекте (Change Requests)**
- *Описание:* Документация запросов на изменения в проекте с оценкой их влияния и необходимости.
- *Ответственный стейкхолдер:* Менеджер проекта.
- *Стейкхолдер, отвечающий за приемку:* Стейкхолдеры проекта.
- *Стадия разработки:* Фаза выполнения проекта.
- **Утвержденные документы (Approved Documents)**
- *Описание:* Коллекция документов, утвержденных и актуальных для проекта.
- *Ответственный стейкхолдер:* Менеджер проекта.
- *Стейкхолдер, отвечающий за приемку:* Стейкхолдеры проекта.
- *Стадия разработки:* Фаза выполнения проекта.
## 4. Мониторинг и контроль:
- **Тестовая документация (Testing Documentation)**
- *Описание:* Документация, описывающая планы и результаты тестирования проекта.
- *Ответственный стейкхолдер:* Тестировщики и QA-специалисты.
- *Стейкхолдер, отвечающий за приемку:* Технические специалисты и разработчики.
- *Стадия разработки:* Фаза мониторинга и контроля.
- **Отчеты о качестве (Quality Reports)**
- *Описание:* Документация о выполнении качественных требований проекта.
- *Ответственный стейкхолдер:* Менеджер по качеству.
- *Стейкхолдер, отвечающий за приемку:* Стейкхолдеры проекта.
- *Стадия разработки:* Фаза мониторинга и контроля.
- **Протоколы управления изменениями (Change Control Logs)**
- *Описание:* Документация всех изменений, внесенных в проект, и их управление.
- *Ответственный стейкхолдер:* Менеджер проекта.
- *Стейкхолдер, отвечающий за приемку:* Стейкхолдеры проекта.
- *Стадия разработки:* Фаза мониторинга и контроля.
- **Мониторинг выполнения бюджета (Budget Performance Monitoring)**
- *Описание:* Документация о расходах и управлении бюджетом проекта.
- *Ответственный стейкхолдер:* Финансовый аналитик.
- *Стейкхолдер, отвечающий за приемку:* Менеджер проекта.
- *Стадия разработки:* Фаза мониторинга и контроля.
## 5. Завершение:
- **Акт приемки результатов (Acceptance Certificate)**
- *Описание:* Документ, удостоверяющий успешное завершение и прием результатов проекта.
- *Ответственный стейкхолдер:* Менеджер проекта.
- *Стейкхолдер, отвечающий за приемку:* Заказчик или стейкхолдеры проекта.
- *Стадия разработки:* Фаза завершения проекта.
- **Документация по завершению проекта (Project Closure Documentation)**
- *Описание:* Документация, описывающая процесс завершения проекта и результаты его работы.
- *Ответственный стейкхолдер:* Менеджер проекта.
- *Стейкхолдер, отвечающий за приемку:* Стейкхолдеры проекта.
- *Стадия разработки:* Фаза завершения проекта.
- **Отчет об извлеченных уроках (Lessons Learned Report)**
- *Описание:* Документ, содержащий анализ успешных и неуспешных аспектов проекта и извлеченные уроки.
- *Ответственный стейкхолдер:* Менеджер проекта.
- *Стейкхолдер, отвечающий за приемку:* Стейкхолдеры проекта.
- *Стадия разработки:* Фаза завершения проекта.

View File

@ -0,0 +1,135 @@
### Функциональные требования для DualSpace Messenger:
---
### **1. Регистрация и управление учётной записью**
**1.1. Регистрация пользователя**
- **Источник требования:** Все пользователи (фрилансеры, сотрудники компаний, менеджеры).
- **Описание:**
- Регистрация через email (обязательно) или OAuth (Google, Microsoft).
- Поля: email, пароль, тип аккаунта (личный/корпоративный).
- Подтверждение email для активации аккаунта.
- **Приоритет:** Высокий.
**1.2. Вход в систему**
- **Источник требования:** Все пользователи.
- **Описание:**
- Аутентификация по email/паролю или через OAuth.
- Двухфакторная аутентификация (опционально).
- **Приоритет:** Высокий.
---
### **2. Управление режимами (Рабочий/Личный)**
**2.1. Переключение режимов**
- **Источник требования:** Пользователи, совмещающие работу и личное общение.
- **Описание:**
- Кнопка переключения между режимами в интерфейсе.
- Автоматическая фильтрация чатов и уведомлений в зависимости от режима.
- **Приоритет:** Высокий.
**2.2. Настройка контактов по режимам**
- **Источник требования:** Корпоративные клиенты.
- **Описание:**
- Возможность назначать контакты/чаты как «Рабочие» или «Личные».
- Запрет на добавление личных контактов в корпоративном режиме (для компаний).
- **Приоритет:** Средний.
---
### **3. Управление чатами и сообщениями**
**3.1. Создание чатов**
- **Источник требования:** Все пользователи.
- **Описание:**
- Создание личных и групповых чатов.
- Выбор типа чата (рабочий/личный) при создании.
- **Приоритет:** Высокий.
**3.2. Интеграция файлов и сервисов**
- **Источник требования:** Разработчики, дизайнеры, менеджеры.
- **Описание:**
- Прикрепление файлов (PDF, Figma, код).
- Превью для файлов (например, встроенный просмотр Figma).
- **Приоритет:** Высокий.
**3.3. Шаблоны сообщений**
- **Источник требования:** Менеджеры по продажам, поддержке.
- **Описание:**
- Создание и использование шаблонов для частых ответов.
- Быстрый доступ к шаблонам через хоткеи.
- **Приоритет:** Средний.
---
### **4. Интеграции с внешними сервисами**
**4.1. Календарь и встречи**
- **Источник требования:** Удалённые команды, фрилансеры.
- **Описание:**
- Синхронизация с Google Calendar, Outlook.
- Создание встреч с автоматической генерацией ссылок (Zoom, Google Meet).
- **Приоритет:** Высокий.
**4.2. Интеграция с инструментами разработки**
- **Источник требования:** ИТ-команды.
- **Описание:**
- Уведомления из Jira/GitHub о задачах прямо в чат.
- Возможность создавать задачи из сообщений.
- **Приоритет:** Средний.
---
### **5. Уведомления и безопасность**
**5.1. Гибкие настройки уведомлений**
- **Источник требования:** Все пользователи.
- **Описание:**
- Настройка уведомлений по режимам (например, отключение личных уведомлений в рабочее время).
- Кастомизация звуков и типов оповещений.
- **Приоритет:** Высокий.
**5.2. Сквозное шифрование**
- **Источник требования:** Корпоративные клиенты, фрилансеры.
- **Описание:**
- Шифрование для выбранных чатов (включая вложения).
- Поддержка протоколов безопасности (например, TLS).
- **Приоритет:** Высокий.
---
### **6. Статистика и аналитика**
**6.1. Аналитика активности**
- **Источник требования:** Руководители, владельцы бизнеса.
- **Описание:**
- Отчёты по времени, проведённому в рабочих чатах.
- Статистика по выполненным задачам (интеграция с Jira).
- **Приоритет:** Средний.
---
### **7. Управление профилем и настройками**
**7.1. Редактирование профиля**
- **Источник требования:** Все пользователи.
- **Описание:**
- Добавление аватара, статуса, контактных данных.
- Настройка видимости профиля (для корпоративных аккаунтов).
- **Приоритет:** Средний.
**7.2. Управление доступом (для компаний)**
- **Источник требования:** Администраторы организаций.
- **Описание:**
- Назначение ролей (сотрудник, менеджер, администратор).
- Ограничение доступа к чатам для новых участников.
- **Приоритет:** Высокий.
---
### **Приоритеты**
- **Высокий:** Функции, критичные для MVP (регистрация, чаты, переключение режимов, интеграция с календарём).
- **Средний:** Дополнительные возможности для улучшения UX (шаблоны, аналитика).
- **Низкий:** Нишевые функции (например, кастомные темы оформления).

View File

@ -0,0 +1,144 @@
### Нефункциональные требования для DualSpace Messenger:
---
### **1. Производительность**
**1.1. Скорость доставки сообщений**
- **Источник требования:** Пользователи, техническая команда.
- **Описание:** Сообщения должны доставляться в режиме реального времени.
- **Параметры:**
- Задержка доставки сообщений ≤ 1 сек (для 95% запросов).
- Время отклика интерфейса при отправке сообщения ≤ 500 мс.
- **Приоритет:** Высокий.
**1.2. Нагрузочная устойчивость**
- **Источник требования:** Техническая команда.
- **Описание:** Система должна выдерживать пиковые нагрузки (например, массовая отправка сообщений).
- **Параметры:**
- Поддержка 10,000 одновременных пользователей на одном сервере.
- Обработка до 1,000 сообщений в секунду.
- **Приоритет:** Высокий.
---
### **2. Надёжность**
**2.1. Доступность сервиса**
- **Источник требования:** Все пользователи.
- **Описание:** Минимизация времени простоя.
- **Параметры:**
- Доступность 99.99% (SLA).
- Время восстановления после сбоя (MTTR) ≤ 15 минут.
- **Приоритет:** Высокий.
**2.2. Резервное копирование данных**
- **Источник требования:** Администраторы, юристы.
- **Описание:** Гарантия сохранности данных при сбоях.
- **Параметры:**
- Ежечасное резервное копирование чатов и метаданных.
- Хранение резервных копий ≥ 30 дней.
- **Приоритет:** Высокий.
---
### **3. Безопасность**
**3.1. Шифрование данных**
- **Источник требования:** Корпоративные клиенты, юристы.
- **Описание:** Защита конфиденциальной информации.
- **Параметры:**
- Сквозное шифрование (E2EE) для сообщений и вложений.
- Поддержка TLS 1.3 для передачи данных.
- **Приоритет:** Высокий.
**3.2. Аутентификация и авторизация**
- **Источник требования:** Техническая команда.
- **Описание:** Предотвращение несанкционированного доступа.
- **Параметры:**
- Обязательная двухфакторная аутентификация (2FA) для корпоративных аккаунтов.
- Сессии автоматически завершаются после 30 минут неактивности.
- **Приоритет:** Высокий.
---
### **4. Масштабируемость**
**4.1. Горизонтальное масштабирование**
- **Источник требования:** Техническая команда.
- **Описание:** Поддержка роста пользовательской базы.
- **Параметры:**
- Возможность добавления серверов без прерывания работы.
- Автоматическая балансировка нагрузки (например, Kubernetes).
- **Приоритет:** Средний.
**4.2. Интеграция с облачными сервисами**
- **Источник требования:** Техническая команда.
- **Описание:** Гибкость развёртывания.
- **Параметры:**
- Поддержка AWS, Google Cloud, Azure, Я.Облако.
- Автомасштабирование при увеличении нагрузки на 50%.
- **Приоритет:** Средний.
---
### **5. Совместимость**
**5.1. Кроссплатформенность**
- **Источник требования:** Все пользователи.
- **Описание:** Работа на всех популярных ОС и устройствах.
- **Параметры:**
- Поддержка: iOS 14+, Android 10+, Windows 10+, macOS 11+.
- Веб-версия: Chrome, Firefox, Safari, Edge (последние 2 версии).
- **Приоритет:** Высокий.
**5.2. Интеграция со сторонними сервисами**
- **Источник требования:** Пользователи (ИТ-команды, фрилансеры).
- **Описание:** Совместимость с инструментами разработки и видеоконференций.
- **Параметры:**
- Поддержка API Zoom, Google Meet, Jira, GitHub.
- Обновление интеграций при выходе новых версий API.
- **Приоритет:** Средний.
---
### **6. Удобство использования (Usability)**
**6.1. Отзывчивый интерфейс**
- **Источник требования:** Все пользователи.
- **Описание:** Интуитивный дизайн для снижения времени обучения.
- **Параметры:**
- 95% пользователей осваивают базовые функции за ≤ 10 минут.
- Рейтинг удовлетворённости интерфейсом ≥ 4.5/5 (на основе опросов).
- **Приоритет:** Высокий.
---
### **7. Локализация**
**7.1. Поддержка языков**
- **Источник требования:** Международные пользователи.
- **Описание:** Адаптация под разные регионы.
- **Параметры:**
- Поддержка английского, русского, испанского, немецкого языков на старте.
- Локализация дат, валют и единиц измерения.
- **Приоритет:** Низкий.
---
### **8. Документация**
**8.1. Техническая документация**
- **Источник требования:** Разработчики, администраторы.
- **Описание:** Подробные руководства для интеграции и поддержки.
- **Параметры:**
- OpenAPI-спецификация для публичных API.
- Примеры кода на Kotlin, JavaScript.
- **Приоритет:** Средний.
---
### **Приоритеты**
- **Высокий:** Безопасность, доступность, скорость доставки сообщений.
- **Средний:** Масштабируемость, интеграции, документация.
- **Низкий:** Локализация, кастомные темы.

View File

@ -0,0 +1,99 @@
# API
---
## Сущность **Chat** (Чат)
**Поля:**
1. **id** (string) — уникальный идентификатор чата (UUID).
2. **title** (string) — название чата (для групповых чатов).
3. **type** (enum: `private`, `group`, `channel`) — тип чата.
4. **mode** (enum: `work`, `personal`) — режим чата (рабочий/личный).
5. **participants** (array of user IDs) — список участников.
6. **created_at** (timestamp) — дата создания.
7. **is_archived** (boolean) — флаг архивации.
8. **metadata** (JSON) — дополнительные данные (например, `{"project_id": "abc123", "jira_link": "..."}`).
---
### Эндпоинты для **Chat**
| Метод | Путь | Описание | Параметры |
|-------|--------------------------|-------------------------------------------|---------------------------------------------------------------------------|
| POST | `/api/v1/chats` | Создать чат | `{ title, type, mode, participants }` |
| GET | `/api/v1/chats/{id}` | Получить чат по ID | — |
| PATCH | `/api/v1/chats/{id}` | Обновить чат (название, режим, архив) | `{ title?, mode?, is_archived? }` |
| DELETE | `/api/v1/chats/{id}` | Архивировать чат | — |
| GET | `/api/v1/chats` | Поиск чатов | `?type=group&mode=work&participant=user123&search=project` |
| POST | `/api/v1/chats/{id}/join`| Добавить участника | `{ user_id }` |
| POST | `/api/v1/chats/{id}/leave`| Удалить участника | `{ user_id }` |
---
## Сущность **Message** (Сообщение)
**Поля:**
1. **id** (string) — уникальный идентификатор сообщения (UUID).
2. **chat_id** (string) — ID чата.
3. **sender_id** (string) — ID отправителя.
4. **text** (string) — текст сообщения (может быть `null` для вложений).
5. **attachments** (array) — вложения:
`{ type: "file" | "link" | "meeting", url: string, preview?: string }`.
6. **timestamp** (timestamp) — время отправки.
7. **status** (enum: `sent`, `delivered`, `read`) — статус сообщения.
8. **metadata** (JSON) — дополнительные данные (хештеги, упоминания).
---
### Эндпоинты для **Message**
| Метод | Путь | Описание | Параметры |
|-------|-------------------------------------|-------------------------------------------|---------------------------------------------------------------------------|
| POST | `/api/v1/chats/{chat_id}/messages` | Отправить сообщение | `{ text?, attachments[], metadata? }` |
| GET | `/api/v1/messages/{id}` | Получить сообщение по ID | — |
| DELETE | `/api/v1/messages/{id}` | Удалить сообщение (для отправителя) | — |
| GET | `/api/v1/chats/{chat_id}/messages` | Получить историю сообщений | `?limit=50&offset=0&search=bug&from=2023-01-01&to=2023-12-31` |
| PATCH | `/api/v1/messages/{id}/status` | Обновить статус (например, `read`) | `{ status }` |
---
### Примеры запросов
**Создание чата:**
```http
POST /api/v1/chats
Body:
{
"type": "group",
"mode": "work",
"title": "Project Alpha",
"participants": ["user1", "user2"]
}
```
**Поиск сообщений:**
```http
GET /api/v1/chats/chat123/messages?search=deadline&from=2023-10-01
```
**Отправка сообщения с вложением:**
```http
POST /api/v1/chats/chat123/messages
Body:
{
"text": "Проверьте новый дизайн",
"attachments": [
{ "type": "file", "url": "https://.../design.pdf", "preview": "https://.../preview.png" }
]
}
```
---
### Особенности:
1. **Авторизация:** Все запросы требуют токена (JWT в заголовке `Authorization`).
2. **Ошибки:**
- `403 Forbidden` — пользователь не является участником чата.
- `404 Not Found` — чат/сообщение не существует.
- `400 Bad Request` — неверный формат вложений.
3. **Пагинация:** Для списков используется `limit` и `offset` (по умолчанию `limit=20`).
---

View File

@ -0,0 +1,13 @@
# Компонентная схема
## Диаграмма контекста C4
![Диаграмма контекста C4](../imgs/C4-context.drawio.png)
## Диаграмма контейнеров C4
![Диаграмма контейнеров C4](../imgs/C4-containers.drawio.png)
## Упрощенная (луковичная) диаграмма компонентов
![Луковичная диаграмма компонентов](../imgs/onion-arch.drawio.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
docs/imgs/design-layout.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB