Compare commits

...

34 Commits

Author SHA1 Message Date
9e218fe87d vault backup: 2026-04-09 21:30:33 2026-04-09 21:30:33 +03:00
5b1191b398 vault backup: 2026-04-09 21:10:02 2026-04-09 21:10:02 +03:00
1a878d5e98 vault backup: 2026-04-07 14:24:28 2026-04-07 14:24:28 +03:00
134a142774 vault backup: 2026-04-07 11:53:46 2026-04-07 11:53:46 +03:00
0d25cbe8b8 vault backup: 2026-04-05 15:15:22 2026-04-05 15:15:22 +03:00
d3e783f512 vault backup: 2026-04-05 00:48:47 2026-04-05 00:48:47 +03:00
Cosmo
e2cbac051a design: анализ Ultrahuman Ring PRO для вдохновения Pulse 2026-04-02 15:42:49 +00:00
43e271733b vault backup: 2026-04-02 13:59:18 2026-04-02 13:59:19 +03:00
Cosmo
20e1f3fa6c docs: инфраструктура VM Сервисы + архитектура pulse-api и pulse-web 2026-04-02 10:43:44 +00:00
Cosmo
d4f3a10d0d docs: Marzban — план действий при блокировке VPN 2026-04-01 14:09:18 +00:00
ec5f55a897 vault backup: 2026-04-01 14:45:03 2026-04-01 14:45:03 +03:00
cfaf1e8f45 vault backup: 2026-04-01 13:05:39 2026-04-01 13:05:39 +03:00
0f31a7eee6 vault backup: 2026-04-01 12:50:06 2026-04-01 12:50:06 +03:00
f2a00f328f vault backup: 2026-04-01 12:37:58 2026-04-01 12:37:58 +03:00
1ab4f4412d vault backup: 2026-04-01 12:17:06 2026-04-01 12:17:06 +03:00
7c043afd4f vault backup: 2026-04-01 11:23:38 2026-04-01 11:23:38 +03:00
Cosmo
7b2415eeda feat: Cosmo Studio plan — пиксельный офис агентов 2026-03-27 17:58:59 +00:00
b1220f1d2e vault backup: 2026-03-26 14:02:52 2026-03-26 14:02:52 +03:00
d953f87c92 vault backup: 2026-03-26 12:38:28 2026-03-26 12:38:28 +03:00
1ee7afb4b9 Merge remote-tracking branch 'origin/master' 2026-03-26 12:01:37 +03:00
ae1cf8f430 vault backup: 2026-03-26 11:58:28 2026-03-26 11:58:28 +03:00
Cosmo
0569bd5a0f 🗂️ Реструктуризация vault: логичная организация папок
Изменения:
- Интеграция СУП/ → Работа/Интеграция СУП/ (рабочие заметки вместе)
- Релизы/ → Работа/Релизы/ (рабочие заметки вместе)
- Другое/Собеседование .Net → Работа/ (рабочая тема)
- Другое/Своя игра → Личное/ (хобби)
- Smart home/ → Квартира/ (всё про квартиру в одном месте)
- Flutter/, Go/ → Dev/Flutter/, Dev/Go/ (учебные роадмапы)
- Dev/Pulse/competitors-analysis → Projects/Pulse/ (проект Pulse в одной папке)
- Twilio.md → Dev/ (техническая заметка)
- Tokens.md → Личное/Tokens (API keys).md
- Игры.md → Личное/Игры.md
- Удалены пустые папки: Другое/, Smart home/, Интеграция СУП/, Релизы/

Структура:
  Авто/        — автомобили
  Dev/         — разработка, изучение (Go, Flutter, репозитории)
  Квартира/    — квартира + умный дом
  Личное/      — личное, токены, игры, команды
  Мама/        — проекты для мамы
  Projects/    — Pulse App
  Работа/      — BPMSoft, интеграции, релизы
  Япония/      — путешествие
  saved-articles/ — сохранённые статьи
  voice-notes/ — голосовые заметки
2026-03-26 08:52:13 +00:00
Cosmo
5919c0123e 📱 Add Flutter & Dart learning roadmap 2026-03-26 08:18:44 +00:00
06b25a17f9 vault backup: 2026-03-25 10:07:56 2026-03-25 10:07:56 +03:00
feb25cf4ad vault backup: 2026-03-22 13:21:24 2026-03-22 13:21:24 +03:00
4b89753c3e vault backup: 2026-03-22 10:31:13 2026-03-22 10:31:13 +03:00
Cosmo
885ae70062 🔄 auto-sync 2026-03-21 11:00 2026-03-21 11:00:09 +00:00
79c8a9fea9 vault backup: 2026-03-21 08:31:00 2026-03-21 08:31:00 +03:00
Daniil Klimov
8e890ebfd2 vault backup: 2026-03-10 23:55:42 2026-03-10 23:55:42 +09:00
Daniil Klimov
f3c859a1d8 vault backup: 2026-03-08 16:57:56 2026-03-08 16:57:56 +09:00
eb90e621cc vault backup: 2026-02-24 11:47:48 2026-02-24 11:47:48 +03:00
33f6c34d36 vault backup: 2026-02-24 11:45:23 2026-02-24 11:45:24 +03:00
04cb863bd9 Merge remote-tracking branch 'origin/master' 2026-02-24 11:45:23 +03:00
976bedbdbd vault backup: 2026-02-19 18:34:05 2026-02-19 18:34:05 +03:00
68 changed files with 3739 additions and 61 deletions

View File

@@ -35,9 +35,7 @@
"useInternalPlugins": false "useInternalPlugins": false
}, },
"Работа": "LiPcCase", "Работа": "LiPcCase",
"Интеграция СУП": "🤢",
"Мама": "👩‍👦", "Мама": "👩‍👦",
"Другое": "📔",
"Личное": "🧑", "Личное": "🧑",
"Япония": "🎎" "Япония": "🎎"
} }

View File

@@ -0,0 +1,126 @@
# BPMSoft CRM — RAG поиск по коду
Семантический поиск по кодовой базе проекта `C:\Work\BPMSoft\crm`.
Стек: **Qdrant** (векторная БД) + **Ollama nomic-embed-text** (эмбеддинги) + **MCP сервер** для Claude Code + **веб-интерфейс**.
---
## Инфраструктура
| Компонент | Адрес | Описание |
| ---------------- | --------------------------------- | ------------------------ |
| Qdrant | `http://localhost:6333` | Векторная БД, Docker |
| Qdrant Dashboard | `http://localhost:6333/dashboard` | Веб-интерфейс Qdrant |
| Ollama | `http://localhost:11434` | Локальные эмбеддинги |
| Веб-поиск | `http://localhost:8765` | Интерфейс поиска по коду |
Файлы проекта: `C:\Work\BPMSoft\crm\.rag\`
---
## Команды
### Запустить Qdrant (Docker)
```bash
docker start qdrant
```
> Контейнер настроен на `restart=always` — стартует автоматически вместе с Docker.
### Запустить веб-интерфейс поиска
```bash
python C:\Work\BPMSoft\crm\.rag\search_server.py
```
Открыть в браузере: `http://localhost:8765`
### Инкрементальное обновление индекса (только изменённые файлы)
```bash
python C:\Work\BPMSoft\crm\.rag\index_incremental.py
```
Запускать после изменения/добавления файлов в проекте. Работает быстро — обрабатывает только изменённые файлы.
### Полная переиндексация (редко, при крупных изменениях)
```bash
python C:\Work\BPMSoft\crm\.rag\index_codebase.py --reindex
```
> Занимает несколько часов — пересоздаёт всю коллекцию с нуля.
---
## Что индексируется
### C# (`BPMSoft.Configuration`)
- Методы, конструкторы → тип `method`
- Классы, структуры → тип `class` / `struct`
- Интерфейсы → тип `interface`
- Enum'ы → тип `enum`
- XML doc-комментарии включены в контекст
### JavaScript (`BPMSoft.Configuration`)
- ExtJS BPMSoft схемы (`/Schemas/*.js`) → тип `extjs_schema`
- Методы внутри схем → тип `extjs_method`
- Mixins схем → тип `extjs_mixins`
- Angular/src файлы (`/Files/src/js/`) → `function`, `js_class`, `js_method`
- Autogenerated JS платформы (`/Autogenerated/Src/`)
### Исключено из индекса
- `SvnPackages/` — SVN пакеты
- `node_modules/`, `bin/`, `obj/`, `dist/`
- `*.min.js` — минифицированные файлы
- Angular build cache `/.nx/`
---
## MCP сервер для Claude Code
Зарегистрирован автоматически. Доступные инструменты:
| Инструмент | Описание |
|------------|----------|
| `search_codebase` | Семантический поиск по запросу |
| `find_symbol` | Поиск класса/метода по имени |
| `find_in_namespace` | Все символы в namespace или по пути |
### Регистрация вручную (если слетела)
```bash
claude mcp add --transport stdio crm-rag -- cmd /c python C:\Work\BPMSoft\crm\.rag\mcp_server.py
```
### Проверить статус
```bash
claude mcp list
```
---
## Файлы
```
C:\Work\BPMSoft\crm\.rag\
├── index_codebase.py # Полная индексация
├── index_incremental.py # Инкрементальное обновление
├── mcp_server.py # MCP сервер для Claude Code
├── search_server.py # Веб-сервер поиска (FastAPI)
├── search_ui.html # Интерфейс поиска
├── file_hashes.json # Хеши файлов для инкрементальной индексации
└── qdrant_storage/ # Данные Qdrant (Docker volume)
```
---
## Зависимости Python
```bash
pip install qdrant-client tree-sitter tree-sitter-c-sharp tree-sitter-javascript requests fastapi uvicorn mcp
```
---
## Управление Docker контейнером
```bash
docker ps | grep qdrant # статус
docker stop qdrant # остановить
docker start qdrant # запустить
docker logs qdrant # логи
docker restart qdrant # перезапустить
```

0
Companies.md Normal file
View File

202
Dev/Cosmo Studio.md Normal file
View File

@@ -0,0 +1,202 @@
# Cosmo Studio — Пиксельный офис агентов
> Веб-дашборд в реальном времени: Cosmo, Люся и Claude Coding как пиксельные персонажи в виртуальном офисе.
## Концепция
Открываешь браузер → видишь офис. Я пишу тебе ответ → мой персонаж печатает за компьютером. Агент закончил работу → идёт на диван в зону отдыха. Люся думает → её персонаж чешет голову.
**Стек:**
- Frontend: React + Canvas 2D (пиксель-арт офис)
- Backend: Node.js + WebSocket (мост между OpenClaw и браузером)
- Хостинг: VM Сервисы → `studio.digital-home.site`
- Спрайты: из репозитория AgentRoom (MIT лицензия)
---
## Этапы
### Этап 0 — Подготовка (1-2 дня)
**0.1 Открыть OpenClaw API для VM Сервисов**
- Сейчас `gateway.bind = "lan"` — уже слушает на LAN интерфейсе (192.168.31.103:18789)
- VM Сервисы (192.168.31.60) должна быть в той же сети → проверить пинг
- Если не достучаться: включить `gateway.bind = "lan"` явно + проверить firewall
- Аутентификация: токен уже настроен в конфиге
**0.2 Скачать спрайты из AgentRoom**
Репозиторий: https://github.com/liuyixin-louis/agentroom
Нужные файлы:
- `agentroom-visual/public/assets/` — тайлсеты офиса (SkyOffice: FloorAndGround, Modern_Office)
- `agentroom-visual/public/assets/characters/` — спрайты персонажей (JIK-A-4 Metro City)
- Каждый персонаж: 4 направления × 3 кадра = 12 спрайтов (idle, walk, type)
**0.3 Назначить персонажей агентам**
| Агент | Персонаж | Цвет |
|-------|----------|------|
| Cosmo (main) | Синий character | #3B82F6 |
| Люся (wife) | Розовый character | #EC4899 |
| Claude Coding | Зелёный character | #10B981 |
| Claude Research | Фиолетовый character | #8B5CF6 |
---
### Этап 1 — OpenClaw Bridge (2-3 дня)
**Задача:** Node.js сервис на VM Сервисы, который подключается к OpenClaw WebSocket API и транслирует события агентов.
**Структура:** `/opt/digital-home/cosmo-studio/bridge/`
```
bridge/
├── index.js # WebSocket клиент к OpenClaw
├── state.js # Состояние всех агентов
├── server.js # WebSocket сервер → браузер
└── parser.js # Разбор JSONL событий
```
**Логика определения состояния агента:**
OpenClaw sessions API: `GET http://192.168.31.103:18789/sessions`
WebSocket events: `ws://192.168.31.103:18789`
Из JSONL событий:
```
toolCall → agent = "typing" (пишет)
toolResult → agent = "reading" (читает/думает)
text block → agent = "sending" (отправляет)
session idle → agent = "idle" (свободен)
session running → agent = "working"
```
**Состояния персонажа:**
- `idle` → сидит за столом, анимация дыхания
- `typing` → руки на клавиатуре, быстрая анимация
- `thinking` → смотрит в экран, медленная анимация
- `walking` → движется по офису (BFS pathfinding)
- `break` → на диване в Break Room
- `waiting` → speech bubble "⏳"
---
### Этап 2 — Офисный движок (3-4 дня)
**Задача:** React + Canvas 2D рендерер с тайлсетами и персонажами.
**Структура:** `/opt/digital-home/cosmo-studio/frontend/`
```
src/
├── engine/
│ ├── Renderer.ts # Canvas 2D loop (requestAnimationFrame)
│ ├── TilesetManager.ts # Загрузка и рендер тайлов
│ ├── Character.ts # Спрайт + анимация + позиция
│ ├── Pathfinding.ts # BFS по офисной сетке
│ └── OfficeLayout.ts # Карта офиса (столы, диваны, зоны)
├── components/
│ ├── Office.tsx # Основной Canvas компонент
│ ├── AgentCard.tsx # Карточка агента (статус, токены)
│ └── EventFeed.tsx # Лента событий (последние действия)
├── hooks/
│ └── useAgentEvents.ts # WebSocket → состояния агентов
└── App.tsx
```
**Офисная карта (32×24 тайла, каждый 32px = 1024×768px):**
```
┌─────────────────────────────────┐
│ [💻 Desk Cosmo] [💻 Desk Люся] │ ← Work Room
│ [💻 Desk Coding] [💻 Desk Res] │
├─────────────────────────────────┤
│ [🛋️ Couch] [🌱 Plant] [TV] │ ← Break Room
└─────────────────────────────────┘
```
**Логика переходов:**
- Агент стал `working` → персонаж идёт к своему столу (BFS)
- Агент стал `idle` → персонаж идёт в Break Room
- Агент `typing` → анимация печати
- Два агента встретились → speech bubble "👋"
---
### Этап 3 — UI панели (1-2 дня)
**Боковая панель:**
- Список агентов: имя + статус + текущее действие
- Токены: потрачено сегодня, неделя
- Последнее сообщение (первые 60 символов)
**Нижняя панель — лента событий:**
```
17:42 Cosmo → отвечает Даниилу (telegram)
17:41 Coding → читает файл main.go
17:40 Люся → обрабатывает heartbeat
```
**Верхняя панель:**
- Дата/время
- Кнопка "Open in Telegram" → deep link
- Индикатор здоровья системы
---
### Этап 4 — Деплой (1 день)
```yaml
# /opt/digital-home/cosmo-studio/docker-compose.yml
services:
cosmo-studio:
build: .
ports:
- "3400:3400"
environment:
- OPENCLAW_URL=ws://192.168.31.103:18789
- OPENCLAW_TOKEN=${OPENCLAW_TOKEN}
networks:
- services_proxy
restart: unless-stopped
networks:
services_proxy:
external: true
```
NPM proxy host: `studio.digital-home.site``cosmo-studio:3400`
---
## Что нужно решить заранее
1. **OpenClaw WebSocket API** — какие именно события транслирует, нужно изучить документацию `/home/daniil/.npm-global/lib/node_modules/openclaw/docs`
2. **Firewall между VPS и VM Сервисы** — сейчас VM Сервисы не видит gateway. Вариант: открыть порт 18789 в ufw на VPS, или использовать SSH tunnel.
3. **Спрайты** — нужно клонировать репо и выбрать конкретные файлы из `agentroom-visual/public/assets/`
4. **Аутентификация дашборда** — добавить basic auth через NPM или JWT
---
## Оценка времени
| Этап | Работа |
|------|--------|
| 0. Подготовка | 1-2 дня |
| 1. Bridge сервис | 2-3 дня |
| 2. Офисный движок | 3-4 дня |
| 3. UI панели | 1-2 дня |
| 4. Деплой | 1 день |
| **Итого** | **~2 недели** |
---
## Статус
- [ ] Этап 0: Подготовка
- [ ] Этап 1: Bridge сервис
- [ ] Этап 2: Офисный движок
- [ ] Этап 3: UI панели
- [ ] Этап 4: Деплой
*Создано: 2026-03-27*

543
Dev/Flutter/Roadmap.md Normal file
View File

@@ -0,0 +1,543 @@
---
title: "Flutter & Dart Roadmap"
date: 2026-03-26
tags:
- flutter
- dart
- mobile
- roadmap
- learning
description: "Подробный план изучения Flutter и Dart для опытного разработчика (C#, Go, JS)"
---
# 🚀 Flutter & Dart Roadmap
> **Цель:** Самостоятельно создавать мобильные приложения (iOS + Android)
> **Опыт:** C#, Go, JavaScript — базовые концепции ООП, async, типизация уже знакомы
> **Общая оценка:** ~120160 часов / 34 месяца при 810 ч/неделю
---
## 📋 Оглавление
1. [[#Этап 1 — Dart за 1 неделю|Dart за 1 неделю]]
2. [[#Этап 2 — Flutter основы|Flutter основы (2 недели)]]
3. [[#Этап 3 — Навигация и архитектура|Навигация и архитектура (1.5 недели)]]
4. [[#Этап 4 — State Management|State Management (2 недели)]]
5. [[#Этап 5 — Работа с данными|Работа с данными (2 недели)]]
6. [[#Этап 6 — UI мастерство|UI мастерство (1.5 недели)]]
7. [[#Этап 7 — Нативные возможности|Нативные возможности (1 неделя)]]
8. [[#Этап 8 — Тестирование и CI/CD|Тестирование и CI/CD (1 неделя)]]
9. [[#Этап 9 — Публикация|Публикация в Store (1 неделя)]]
10. [[#Этап 10 — Реальный проект|Реальный проект (46 недель)]]
11. [[#Ресурсы — Каталог|Каталог ресурсов]]
---
## Этап 1 — Dart за 1 неделю
**~812 часов** | С опытом в C# и JS пойдёт быстро
Dart — типизированный язык, похожий на гибрид C# и TypeScript. Основные отличия: null safety, mixins, extensions, Futures/Streams (аналог Task/Promise).
### Что изучить
- [x] Синтаксис: переменные, типы, `final`/`const`, `late` ✅ 2026-03-26
- [x] Null safety (`?`, `!`, `??`, `?.`) ✅ 2026-03-26
- [ ] Классы, наследование, mixins, abstract classes
- [ ] Extensions (привет, C# extension methods)
- [ ] Enums (enhanced enums с методами — Dart 3)
- [ ] Generics (знакомо из C#)
- [ ] Collections: `List`, `Map`, `Set` + spread operator
- [ ] `async`/`await`, `Future`, `Stream`
- [ ] Pattern matching и sealed classes (Dart 3) — аналог switch expressions в C#
- [ ] Records (аналог tuples/анонимных типов)
- [ ] Error handling: `try`/`catch`/`on`
### Ресурсы
- [ ] 📖 [Dart Language Tour](https://dart.dev/language) — **главный ресурс**, пробежать за 34 часа
- [ ] 📖 [Dart Codelabs](https://dart.dev/codelabs) — интерактивные упражнения
- [ ] 🎮 [DartPad](https://dartpad.dev/) — онлайн-песочница для экспериментов
- [ ] 📹 [Dart in 100 Seconds — Fireship](https://www.youtube.com/watch?v=NrO0CJCbYLA) — быстрый обзор
- [ ] 📖 [Effective Dart](https://dart.dev/effective-dart) — стайл-гайд и идиомы
### 🛠 Мини-проект
**CLI-утилита на Dart** — парсер JSON/CSV, конвертер валют через API, или простой todo-list в терминале. Цель: потрогать язык руками.
```bash
dart create my_cli_app
```
---
## Этап 2 — Flutter основы
**~1620 часов / 2 недели**
### Что изучить
- [ ] Установка Flutter SDK + настройка IDE (VS Code / Android Studio)
- [ ] Эмуляторы: Android (AVD) + iOS Simulator (если есть Mac)
- [ ] Структура проекта Flutter: `lib/`, `pubspec.yaml`, `assets/`
- [ ] **Widget tree** — всё является виджетом
- [ ] `StatelessWidget` vs `StatefulWidget` + `setState()`
- [ ] `BuildContext` и жизненный цикл виджетов
- [ ] Основные виджеты: `Text`, `Container`, `Column`, `Row`, `Stack`, `ListView`, `GridView`
- [ ] `Scaffold`, `AppBar`, `BottomNavigationBar`, `Drawer`
- [ ] Layout: `Expanded`, `Flexible`, `SizedBox`, `Padding`, `Align`
- [ ] Input: `TextField`, `Form`, `FormField`, валидация
- [ ] Кнопки: `ElevatedButton`, `TextButton`, `IconButton`, `FloatingActionButton`
- [ ] `Image`, `Icon`, работа с assets
- [ ] Material Design 3 и `ThemeData`
- [ ] **Hot Reload** — главная суперсила Flutter
### Ресурсы
- [ ] 📖 [Flutter Get Started](https://docs.flutter.dev/get-started) — офиц. туториал установки
- [ ] 📖 [Flutter Widget Catalog](https://docs.flutter.dev/ui/widgets) — каталог виджетов с примерами
- [ ] 📖 [Flutter Codelabs](https://docs.flutter.dev/codelabs) — пошаговые лабы от Google
- [ ] 📹 [Flutter Crash Course for Beginners — Traversy Media](https://www.youtube.com/watch?v=1ukSR1GRtMU) — 1 час, быстрый старт
- [ ] 📹 [Flutter Full Course — Mitch Koko](https://www.youtube.com/watch?v=TclK5gNM_PM) — от начала до продвинутого
- [ ] 📹 [Flutter Widget of the Week — Google](https://www.youtube.com/playlist?list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG) — короткие видео по виджетам
- [ ] 📖 [Flutter Layout Cheat Sheet](https://medium.com/flutter-community/flutter-layout-cheat-sheet-5363348d037e)
### 🛠 Пет-проект: Визитка / Портфолио
Простое приложение-визитка с несколькими экранами:
- [ ] Главный экран с аватаром, именем, описанием
- [ ] Страница с контактами (ссылки, email)
- [ ] Тёмная/светлая тема
---
## Этап 3 — Навигация и архитектура
**~1215 часов / 1.5 недели**
### Что изучить
- [ ] `Navigator` 1.0: `push`, `pop`, named routes
- [ ] `Navigator` 2.0 и декларативная навигация
- [ ] **go_router** — стандарт навигации в 2025+ (рекомендован Google)
- [ ] Deep links и параметры в маршрутах
- [ ] Вложенная навигация (Shell routes, tab navigation)
- [ ] Передача данных между экранами
- [ ] Структура проекта:
- Feature-first vs Layer-first
- Рекомендуемая: `lib/features/<name>/{data, domain, presentation}/`
- [ ] Dependency Injection: `get_it` + `injectable`
- [ ] Repository pattern (знакомо из C#)
### Ресурсы
- [ ] 📖 [go_router docs](https://pub.dev/packages/go_router) — офиц. документация
- [ ] 📖 [Flutter Navigation Guide](https://docs.flutter.dev/ui/navigation) — гайд от Google
- [ ] 📹 [go_router Tutorial — Andrea Bizzotto](https://codewithandrea.com/articles/flutter-navigation-gorouter-go-vs-push/) — подробный разбор
- [ ] 📖 [Flutter App Architecture — Andrea Bizzotto](https://codewithandrea.com/articles/flutter-app-architecture-riverpod-introduction/) — feature-first структура
- [ ] 📹 [Flutter Project Structure — Reso Coder](https://www.youtube.com/watch?v=KjE2IDphA_U)
### 🛠 Пет-проект: Мульти-экранное приложение
Приложение-справочник (рецепты / заметки / фильмы):
- [ ] Список элементов → детальный экран
- [ ] go_router с параметрами
- [ ] Bottom navigation с 3+ табами
- [ ] Поиск и фильтрация
---
## Этап 4 — State Management
**~1620 часов / 2 недели** | Самая важная тема
### Подходы (от простого к сложному)
- [ ] `setState` — для локального состояния
- [ ] `InheritedWidget` — как работает "магия" под капотом
- [ ] **Provider** — простой и понятный (хорош для старта)
- [ ] **Riverpod** ⭐ — эволюция Provider, **рекомендация 2025+**
- Compile-safe, testable, не зависит от BuildContext
- `ref.watch`, `ref.read`, `ref.listen`
- Providers: `Provider`, `StateProvider`, `NotifierProvider`, `AsyncNotifierProvider`, `FutureProvider`, `StreamProvider`
- [ ] **BLoC** — для больших enterprise-приложений
- Events → BLoC → States
- Знакомый паттерн если работал с Redux/MediatR
- [ ] Когда что использовать:
- Маленькое приложение → Riverpod
- Большое/командное → BLoC
- Прототип → setState + Provider
### Ресурсы
- [ ] 📖 [Flutter State Management Guide](https://docs.flutter.dev/data-and-backend/state-mgmt/intro) — офиц. обзор
- [ ] 📖 [Riverpod Documentation](https://riverpod.dev/) — **начни с этого**
- [ ] 📹 [Riverpod 2.0 — Complete Guide — Andrea Bizzotto](https://codewithandrea.com/articles/flutter-state-management-riverpod/) — лучший гайд
- [ ] 📹 [Flutter Riverpod Tutorial — Vandad Nahavandipoor](https://www.youtube.com/watch?v=vtGCteFYs4M)
- [ ] 📖 [BLoC Library](https://bloclibrary.dev/) — офиц. сайт с туториалами
- [ ] 📹 [BLoC Tutorial — Reso Coder](https://www.youtube.com/watch?v=THCkkQ-V1-8)
- [ ] 📖 [Provider Package](https://pub.dev/packages/provider) — документация
### 🛠 Пет-проект: Todo App (с архитектурой)
- [ ] CRUD задач с Riverpod
- [ ] Фильтры: все / активные / завершённые
- [ ] Persistence (SharedPreferences или Hive)
- [ ] Clean Architecture: Data → Domain → Presentation
- [ ] Unit-тесты для бизнес-логики
---
## Этап 5 — Работа с данными
**~1620 часов / 2 недели**
### HTTP и API
- [ ] Пакет `http` — базовые запросы
- [ ] **Dio** — продвинутый HTTP-клиент (interceptors, retry, cancel)
- [ ] Сериализация JSON: `json_serializable` + `build_runner`
- [ ] **Freezed** — генерация data-классов и union types
- [ ] Обработка ошибок сети: `Result` pattern, `Either`
- [ ] Retrofit (знакомо из .NET!) — генерация API-клиента
### Локальное хранение
- [ ] `SharedPreferences` — key-value (как LocalStorage)
- [ ] **Hive** — быстрая NoSQL база
- [ ] **Drift** (бывший Moor) — type-safe SQLite ORM
- [ ] `sqflite` — SQLite напрямую
- [ ] `flutter_secure_storage` — для токенов/паролей
### Firebase (бесплатный tier)
- [ ] Firebase Auth — аутентификация
- [ ] Cloud Firestore — NoSQL база
- [ ] Firebase Storage — файлы
- [ ] Firebase Messaging (FCM) — push-нотификации
- [ ] [FlutterFire](https://firebase.flutter.dev/) — офиц. плагины
### Ресурсы
- [ ] 📖 [Flutter Networking Guide](https://docs.flutter.dev/data-and-backend/networking)
- [ ] 📖 [Dio Package](https://pub.dev/packages/dio) — документация
- [ ] 📖 [Freezed Package](https://pub.dev/packages/freezed) — генерация моделей
- [ ] 📖 [FlutterFire Docs](https://firebase.flutter.dev/) — Firebase для Flutter
- [ ] 📹 [Flutter REST API Tutorial — Vandad](https://www.youtube.com/watch?v=CQuxU8JGJnQ)
- [ ] 📹 [Firebase Flutter Course — freeCodeCamp](https://www.youtube.com/watch?v=wUSkeTaBonA) — 5+ часов
- [ ] 📖 [Drift Documentation](https://drift.simonbinder.eu/docs/getting-started/)
### 🛠 Пет-проект: Погодное приложение
- [ ] Запрос к Open-Meteo или OpenWeatherMap API
- [ ] Модели через `freezed` + `json_serializable`
- [ ] Поиск города, текущая погода + прогноз на 5 дней
- [ ] Кэширование последнего запроса в Hive
- [ ] Pull-to-refresh
- [ ] Красивый UI с анимациями погоды
---
## Этап 6 — UI мастерство
**~1215 часов / 1.5 недели**
### Что изучить
- [ ] Animations: implicit (`AnimatedContainer`, `AnimatedOpacity`) и explicit (`AnimationController`, `Tween`)
- [ ] Hero animations (переходы между экранами)
- [ ] Custom Paint — рисование кастомных элементов
- [ ] `Sliver` виджеты: `CustomScrollView`, `SliverAppBar`, `SliverList`, `SliverGrid`
- [ ] Responsive design: `LayoutBuilder`, `MediaQuery`, `OrientationBuilder`
- [ ] Adaptive UI: Material (Android) + Cupertino (iOS)
- [ ] Custom widgets: composition vs inheritance
- [ ] Themes и дизайн-система (typography, color schemes, spacing)
- [ ] Пакеты для UI:
- `flutter_animate` — декларативные анимации
- `shimmer` — loading placeholders
- `cached_network_image` — кэширование картинок
- `flutter_svg` — SVG поддержка
### Ресурсы
- [ ] 📖 [Flutter Animations Guide](https://docs.flutter.dev/ui/animations)
- [ ] 📹 [Flutter Animations Course — Flutter Official](https://www.youtube.com/watch?v=IVTjpW3W33s)
- [ ] 📖 [Flutter Adaptive Design](https://docs.flutter.dev/ui/adaptive-responsive)
- [ ] 📹 [Sliver Widgets — Flutter](https://www.youtube.com/watch?v=Mz3kHQxBjGg)
- [ ] 📖 [Material 3 in Flutter](https://docs.flutter.dev/ui/design/material)
### 🛠 Пет-проект: Клон UI известного приложения
Выбери и воспроизведи UI (без бэкенда):
- [ ] Spotify / Netflix / Twitter — карточки, списки, анимации
- [ ] Кастомные анимации переходов
- [ ] Адаптивный дизайн под разные размеры экрана
- [ ] Тёмная и светлая темы
---
## Этап 7 — Нативные возможности
**~810 часов / 1 неделя**
### Что изучить
- [ ] Platform channels — вызов нативного кода (Swift/Kotlin)
- [ ] Камера: `camera`, `image_picker`
- [ ] Геолокация: `geolocator`, `geocoding`
- [ ] Карты: `google_maps_flutter` или `flutter_map` (OpenStreetMap)
- [ ] Push-уведомления: `firebase_messaging` + `flutter_local_notifications`
- [ ] Permissions: `permission_handler`
- [ ] Biometrics: `local_auth`
- [ ] Deep links и Universal links
- [ ] Sharing: `share_plus`
- [ ] URL launcher: `url_launcher`
### Ресурсы
- [ ] 📖 [Flutter Platform Integration](https://docs.flutter.dev/platform-integration/platform-channels)
- [ ] 📖 [pub.dev](https://pub.dev/) — поиск пакетов, проверяй likes и pub points
- [ ] 📹 [Google Maps in Flutter — Johannes Milke](https://www.youtube.com/watch?v=Zz5hMvgiWmY)
- [ ] 📖 [Flutter Camera Plugin](https://pub.dev/packages/camera)
### 🛠 Мини-проект: Приложение с картой
- [ ] Показать текущее местоположение на карте
- [ ] Добавление маркеров / POI
- [ ] Поиск мест
- [ ] Разрешения runtime
---
## Этап 8 — Тестирование и CI/CD
**~810 часов / 1 неделя**
### Что изучить
- [ ] **Unit tests** — тестирование бизнес-логики и репозиториев
- [ ] **Widget tests** — тестирование UI-компонентов
- [ ] **Integration tests** — E2E тестирование на устройстве/эмуляторе
- [ ] Mocking: `mocktail` или `mockito`
- [ ] Golden tests — скриншот-тесты UI
- [ ] Code coverage: `flutter test --coverage`
- [ ] CI/CD:
- GitHub Actions / Codemagic / Fastlane
- Автоматическая сборка APK/IPA
- Автоматическая публикация в stores
### Ресурсы
- [ ] 📖 [Flutter Testing Guide](https://docs.flutter.dev/testing) — офиц. документация
- [ ] 📹 [Flutter Testing Tutorial — Reso Coder](https://www.youtube.com/watch?v=RDY6UYh-4dg)
- [ ] 📖 [Codemagic CI/CD](https://docs.codemagic.io/flutter/getting-started/) — бесплатный tier для Flutter
- [ ] 📖 [Mocktail Package](https://pub.dev/packages/mocktail)
### 🛠 Практика
- [ ] Написать тесты для Todo App из Этапа 4
- [ ] Unit tests для API-слоя (mock HTTP)
- [ ] Widget tests для ключевых экранов
- [ ] Настроить CI pipeline (GitHub Actions)
---
## Этап 9 — Публикация
**~68 часов / 1 неделя**
### Google Play Store
- [ ] Создать аккаунт разработчика ($25 одноразово)
- [ ] Подписать APK/AAB (keystore)
- [ ] Скриншоты, описание, иконка
- [ ] Privacy Policy (можно сгенерировать)
- [ ] Загрузить в Google Play Console
- [ ] Internal testing → Closed testing → Production
### Apple App Store
- [ ] Apple Developer Program ($99/год)
- [ ] Certificates, Identifiers, Profiles
- [ ] Archive и загрузка через Xcode / Transporter
- [ ] App Store Connect: метаданные, скриншоты
- [ ] TestFlight для бета-тестирования
- [ ] Ревью Apple (строгие правила)
### Ресурсы
- [ ] 📖 [Flutter Deployment — Android](https://docs.flutter.dev/deployment/android)
- [ ] 📖 [Flutter Deployment — iOS](https://docs.flutter.dev/deployment/ios)
- [ ] 📹 [Publish Flutter App — Mitch Koko](https://www.youtube.com/watch?v=g0GNuoCOtaQ)
- [ ] 📖 [Fastlane for Flutter](https://docs.flutter.dev/deployment/cd)
---
## Этап 10 — Реальный проект
**~4060 часов / 46 недель** | Всё вместе
### План создания реального приложения
> Пример: **Personal Finance Tracker** (или любое приложение по интересу)
#### Фаза 1: Планирование (23 дня)
- [ ] Определить MVP: 35 ключевых фич
- [ ] Wireframes (можно в Figma — бесплатно)
- [ ] Выбрать стек: Riverpod + go_router + Dio + Drift/Hive
- [ ] Спроектировать data models
#### Фаза 2: Скелет (1 неделя)
- [ ] Настроить проект с правильной структурой (feature-first)
- [ ] Настроить DI (get_it + injectable)
- [ ] Навигация (go_router)
- [ ] Базовый UI каждого экрана (placeholder)
- [ ] Тема и дизайн-система
#### Фаза 3: Core Features (23 недели)
- [ ] Реализовать основную бизнес-логику
- [ ] Подключить API / базу данных
- [ ] State management для каждой фичи
- [ ] Обработка ошибок и loading states
- [ ] Offline-first: локальный кэш + синхронизация
#### Фаза 4: Polish (1 неделя)
- [ ] Анимации и micro-interactions
- [ ] Responsive дизайн
- [ ] Обработка edge-cases
- [ ] Performance: profiling с DevTools
- [ ] Accessibility (семантика для screen readers)
#### Фаза 5: Launch (35 дней)
- [ ] Написать unit + widget тесты (coverage >60%)
- [ ] CI/CD pipeline
- [ ] Подготовить store listing
- [ ] Бета-тест через TestFlight / Internal Testing
- [ ] Релиз 🚀
### Идеи для реальных проектов
| Проект | Чему научит |
|--------|-------------|
| 💰 Финансовый трекер | CRUD, графики, локальная БД, экспорт |
| 📝 Заметки/Markdown | Редактор, файловая система, синхронизация |
| 🏋️ Трекер тренировок | Таймеры, анимации, статистика |
| 🍕 Доставка еды (клон) | Карты, API, корзина, навигация |
| 📰 Новостной агрегатор | RSS, API, кэширование, push |
| 🎵 Музыкальный плеер | Аудио, фоновое воспроизведение, UI |
---
## Ресурсы — Каталог
### 📖 Документация (читать первым делом)
| Ресурс | Описание |
|--------|----------|
| [dart.dev](https://dart.dev/) | Официальная документация Dart |
| [docs.flutter.dev](https://docs.flutter.dev/) | Официальная документация Flutter |
| [pub.dev](https://pub.dev/) | Репозиторий пакетов (как npm/nuget) |
| [Flutter API Reference](https://api.flutter.dev/) | Полный API reference |
| [Material 3 Guidelines](https://m3.material.io/) | Гайдлайны Material Design |
### 📹 YouTube каналы
| Канал | Описание |
|-------|----------|
| [Flutter Official](https://www.youtube.com/@flutterdev) | Widget of the Week, Decoding Flutter |
| [Fireship](https://www.youtube.com/@Fireship) | Быстрые обзоры, "in 100 seconds" |
| [Vandad Nahavandipoor](https://www.youtube.com/@VandadNP) | Google Developer Expert, подробные курсы |
| [Reso Coder](https://www.youtube.com/@ResoCoder) | Clean Architecture, TDD, BLoC |
| [Mitch Koko](https://www.youtube.com/@createdbykoko) | Практичные проекты от 0 до деплоя |
| [Code With Andrea](https://www.youtube.com/@CodeWithAndrea) | Riverpod, архитектура, best practices |
| [The Flutter Way](https://www.youtube.com/@TheFlutterWay) | Красивые UI клоны |
| [dbestech](https://www.youtube.com/@daboratechltd) | Полные проекты с бэкендом |
| [Johannes Milke](https://www.youtube.com/@JohannesMilke) | Короткие туториалы по конкретным фичам |
| [freeCodeCamp](https://www.youtube.com/@freecodecamp) | Длинные полные курсы (37+ часов) |
### 📚 Бесплатные курсы и туториалы
| Ресурс | Описание |
|--------|----------|
| [Flutter Codelabs](https://docs.flutter.dev/codelabs) | Пошаговые лабы от Google |
| [Dart Codelabs](https://dart.dev/codelabs) | Интерактивные упражнения по Dart |
| [Flutter Apprentice (raywenderlich)](https://www.kodeco.com/flutter) | Бесплатные статьи и туториалы |
| [Flutter Gems](https://fluttergems.dev/) | Каталог полезных пакетов по категориям |
| [Awesome Flutter](https://github.com/Solido/awesome-flutter) | Кураторский список ресурсов на GitHub |
| [Flutter Examples](https://github.com/nisrulz/flutter-examples) | Сотни примеров кода |
| [It's All Widgets](https://itsallwidgets.com/) | Галерея Flutter-приложений с исходниками |
### 🧰 Инструменты
| Инструмент | Описание |
|------------|----------|
| [DartPad](https://dartpad.dev/) | Онлайн-песочница |
| [Flutter DevTools](https://docs.flutter.dev/tools/devtools) | Профилирование, отладка, инспектор |
| [Very Good CLI](https://github.com/VeryGoodOpenSource/very_good_cli) | Генератор проектов с best practices |
| [Mason](https://github.com/felangel/mason) | Шаблоны кода (как Yeoman) |
| [Widgetbook](https://www.widgetbook.io/) | Storybook для Flutter виджетов |
### 📦 Must-have пакеты
| Пакет | Категория | Описание |
|-------|-----------|----------|
| `riverpod` | State Management | Реактивное управление состоянием |
| `go_router` | Навигация | Декларативный роутинг |
| `dio` | Networking | HTTP-клиент |
| `freezed` | Code Generation | Immutable модели |
| `json_serializable` | Serialization | JSON ↔ Dart |
| `hive` | Storage | NoSQL БД |
| `drift` | Storage | SQLite ORM |
| `get_it` | DI | Service locator |
| `injectable` | DI | Кодогенерация для get_it |
| `flutter_hooks` | UI | React-style hooks |
| `cached_network_image` | UI | Кэширование картинок |
| `flutter_svg` | UI | SVG поддержка |
| `intl` | i18n | Локализация |
| `mocktail` | Testing | Мокирование |
---
## 💡 Советы от опытного разработчика к опытному
1. **Не читай — делай.** С опытом в C#/Go/JS ты быстро схватишь синтаксис. Открывай DartPad, пиши код.
2. **Flutter ≠ React Native.** Здесь нет DOM. Всё — виджеты. Widget tree пересоздаётся каждый кадр (Flutter рендерит как игровой движок).
3. **`const` everywhere.** Flutter использует `const` конструкторы для оптимизации rebuilds. Привыкай.
4. **Riverpod > Provider** для новых проектов. Provider legacy, Riverpod — его автор переосмыслил подход.
5. **Не бойся кодогенерации.** `build_runner` — это норма. `freezed` + `json_serializable` сэкономят тонны boilerplate.
6. **Декомпозиция виджетов.** Если `build()` больше 50 строк — разбивай. Extract widget > extract method.
7. **DevTools — твой друг.** Widget Inspector, Performance, Network — используй с первого дня.
8. **Dart — это не JavaScript.** Null safety строгий. Sound typing. Не борись с системой типов — используй её.
---
## 📊 Timeline Summary
| Этап | Тема | Часы | Недели |
|------|------|------|--------|
| 1 | Dart | 812 | 1 |
| 2 | Flutter основы | 1620 | 2 |
| 3 | Навигация и архитектура | 1215 | 1.5 |
| 4 | State Management | 1620 | 2 |
| 5 | Работа с данными | 1620 | 2 |
| 6 | UI мастерство | 1215 | 1.5 |
| 7 | Нативные возможности | 810 | 1 |
| 8 | Тестирование | 810 | 1 |
| 9 | Публикация | 68 | 1 |
| 10 | Реальный проект | 4060 | 46 |
| **Итого** | | **~140190** | **~1719** |
> При 810 часах в неделю = **~45 месяцев** до первого приложения в store 🎯
---
*Создано: 2026-03-26 | Автор: Cosmo ✨*
*Последнее обновление: 2026-03-26*

View File

@@ -1,12 +0,0 @@
https://blitz.digital-home.site:443/eb4643570d60cb40ef62b5bc7c7b92c4/
19 - 100000 (ap +)
20 - 150000 (изменение + - согласование идет) - 1 заявка
21 - 120000 () - 1 заявка (нужно перевыпуск)
22 - ... (успешный ответ) - 1 заявка успех, 2 заявку отправляем
Нужно перевыпустить (логическое - не изменяемое) - Да
Новая
Зарегистрирована
На изменении (изменение данных + согласование)

92
Sing-box.md Normal file
View File

@@ -0,0 +1,92 @@
1. Конфиг
```json
{
"log": {
"level": "info"
},
"dns": {
"servers": [
{
"tag": "google",
"address": "https://8.8.8.8/dns-query",
"address_strategy": "ipv4_only",
"detour": "proxy"
}
],
"strategy": "ipv4_only"
},
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"interface_name": "tun0",
"address": "172.19.0.1/30",
"mtu": 1400,
"auto_route": true,
"strict_route": false,
"stack": "system",
"route_exclude_address": [
"192.168.31.0/24",
"195.135.254.66/32",
"100.64.0.0/10"
]
}
],
"outbounds": [
{
"type": "vless",
"tag": "proxy",
"server": "195.135.254.66",
"server_port": 8888,
"uuid": "96639c6e-553f-4389-95d6-e9e3e808f22f",
"tls": {
"enabled": true,
"server_name": "www.microsoft.com",
"utls": {
"enabled": true,
"fingerprint": "chrome"
},
"reality": {
"enabled": true,
"public_key": "da-vsnYvc3G8nSguWmo0ort1nWBWcFs2nWY_kAcdYjI",
"short_id": "a1b2c3d4"
}
}
},
{
"type": "direct",
"tag": "direct"
}
],
"route": {
"rules": [
{
"protocol": "dns",
"action": "hijack-dns"
},
{
"ip_cidr": [
"192.168.31.0/24",
"100.64.0.0/10"
],
"outbound": "direct"
}
],
"final": "proxy",
"auto_detect_interface": true
}
}
```
2. Команды
```sh
sudo systemctl start sing-box\nsleep 3\ncurl --max-time 5 http://34.160.111.145 -H "Host: ifconfig.me"
sudo ip route add 195.135.254.66/32 via 192.168.31.1 dev ens18 2>/dev/null true
curl --max-time 5 ifconfig.me
sudo systemctl restart sing-box\nsleep 2 sudo ip route add 195.135.254.66/32 via 192.168.31.1 dev ens18 2>/dev/null true\n sudo ip route add 100.64.0.0/10 via 192.168.31.1 dev ens18 2>/dev/null true\n sleep 3\n journalctl -u sing-box -n 10 --no-pager\n curl --max-time 5 ifconfig.me
sudo iptables -t mangle -A POSTROUTING -o ens18 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1000\nsudo iptables -t mangle -A PREROUTING -i ens18 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1000\ncurl --max-time 5 http://34.160.111.145 -H "Host: ifconfig.me"
sudo systemctl stop sing-box
curl --max-time 5 http://34.160.111.145 -H "Host: ifconfig.me"
sudo tcpdump -i ens18 -n 'host 195.135.254.66' -c 10 &\nsleep 1\ncurl --max-time 3 http://34.160.111.145 -H "Host: ifconfig.me"
sudo systemctl start sing-box\nsleep 2\nsudo tcpdump -i ens18 -n 'host 195.135.254.66' -c 10 &\nsleep 1\ncurl --max-time 3 http://34.160.111.145 -H "Host: ifconfig.me"
sudo systemctl stop sing-box
```

View File

@@ -0,0 +1,219 @@
# Marzban — план действий при блокировке
> Инфраструктура: VDS Рига `195.135.254.66`, панель `https://daniilvds.duckdns.org:2083/dashboard/`
> Логин: `admin` / `Marzban2026!`
---
## 🚨 Быстрая смена порта
### 1. Меняем порт в Marzban (xray конфиг)
Через браузер:
```
https://daniilvds.duckdns.org:2083/dashboard/
→ Core Settings → Xray Config
→ Меняем "port": 8888 на новый (например 9443)
→ Save
```
Или через API (с любой машины):
```bash
TOKEN=$(curl -s -X POST https://daniilvds.duckdns.org:2083/api/admin/token \
-d "username=admin&password=Marzban2026!" \
-H "Content-Type: application/x-www-form-urlencoded" | python3 -c "import json,sys; print(json.load(sys.stdin)['access_token'])")
# Получить текущий конфиг
curl -s https://daniilvds.duckdns.org:2083/api/core/config \
-H "Authorization: Bearer $TOKEN"
# Применить изменённый конфиг (меняешь port в JSON и применяешь)
curl -s -X PUT https://daniilvds.duckdns.org:2083/api/core/config \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... новый конфиг ... }'
```
### 2. Пробрасываем новый порт в Docker
```bash
ssh root@195.135.254.66
# Редактируем compose
nano /opt/marzban/docker-compose.yml
# Меняем "8888:8888" → "9443:9443"
cd /opt/marzban && docker compose up -d marzban
```
### 3. Обновляем ключи пользователям
Ключи пользователей **обновляются автоматически** — порт меняется во всех ссылках.
Заходишь в панель → выбираешь пользователя → копируешь новую ссылку → отправляешь.
Или через API:
```bash
curl -s https://daniilvds.duckdns.org:2083/api/user/USERNAME \
-H "Authorization: Bearer $TOKEN"
# В поле "links" будет актуальная ссылка с новым портом
```
---
## 👥 Управление пользователями
### Создать пользователя
```bash
curl -s -X POST https://daniilvds.duckdns.org:2083/api/user \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"username": "vasya",
"proxies": {"vless": {}},
"inbounds": {"VLESS_REALITY": []}
}'
```
### Получить ссылку пользователя
```bash
curl -s https://daniilvds.duckdns.org:2083/api/user/vasya \
-H "Authorization: Bearer $TOKEN" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['links'][0])"
```
### Удалить пользователя (отозвать доступ)
```bash
curl -s -X DELETE https://daniilvds.duckdns.org:2083/api/user/vasya \
-H "Authorization: Bearer $TOKEN"
```
### Список всех пользователей
```bash
curl -s "https://daniilvds.duckdns.org:2083/api/users" \
-H "Authorization: Bearer $TOKEN" | python3 -c "import json,sys; [print(u['username'], u['status']) for u in json.load(sys.stdin)['users']]"
```
---
## 🔌 Добавить новый протокол (inbound)
Через **Core Settings → Xray Config** в панели добавляешь новый блок в `inbounds`.
### Shadowsocks (простой, хорошо работает через мобильный)
```json
{
"tag": "SHADOWSOCKS",
"listen": "0.0.0.0",
"port": 8388,
"protocol": "shadowsocks",
"settings": {
"clients": [],
"network": "tcp,udp"
}
}
```
### VLESS + WebSocket + TLS (обходит DPI через CDN/Cloudflare)
```json
{
"tag": "VLESS_WS",
"listen": "0.0.0.0",
"port": 8889,
"protocol": "vless",
"settings": {
"clients": [],
"decryption": "none"
},
"streamSettings": {
"network": "ws",
"security": "none",
"wsSettings": {
"path": "/vpn"
}
}
}
```
После добавления inbound — в настройках пользователя выбрать новый inbound.
---
## ⚡ Устойчивые порты (реже блокируют)
| Порт | Почему безопасен |
|------|-----------------|
| 443 | HTTPS — блокировка убьёт половину интернета |
| 80 | HTTP — аналогично |
| 2083 | cPanel SSL — используется хостингами |
| 2087 | cPanel — аналогично |
| 8443 | Альтернативный HTTPS |
**Переехать на 443:**
1. Остановить Outline/shadowbox: `docker stop shadowbox`
2. Сменить порт Marzban на 443 (через панель + compose)
---
## 🔄 Полезные команды на сервере
```bash
ssh root@195.135.254.66
# Статус контейнеров
cd /opt/marzban && docker compose ps
# Логи Marzban
docker logs marzban-marzban-1 --tail 50
# Логи Caddy (SSL)
docker logs marzban-caddy-1 --tail 20
# Перезапуск Marzban
docker compose restart marzban
# Перезапуск всего стека
docker compose restart
# Обновить образ Marzban
docker compose pull && docker compose up -d
# Занятые порты
ss -tlnp | grep -E "8888|2053|443|80"
```
---
## 🔑 Reality — что делать если начали детектировать
Reality маскируется под настоящий TLS-хендшейк к `www.microsoft.com`. Если заблокировали:
1. Сменить `dest` на другой популярный сайт (например `www.google.com:443` или `www.apple.com:443`)
2. Сгенерировать новую пару ключей:
```bash
docker exec marzban-marzban-1 xray x25519
```
3. Обновить `privateKey`, `publicKey`, `shortIds` в Core Settings
4. Все пользователи получат новые ссылки автоматически (pubkey меняется в ссылке)
---
## 📱 Приложения для клиентов
| Платформа | Приложение | Ссылка |
|-----------|-----------|--------|
| iOS | Karing | https://apps.apple.com/app/karing/id6472431552 |
| Android | Hiddify | https://play.google.com/store/apps/details?id=app.hiddify.com |
| Windows | Hiddify | https://github.com/hiddify/hiddify-app/releases/latest |
| macOS | Hiddify | https://github.com/hiddify/hiddify-app/releases/latest |
---
## 📋 Страница для раздачи ключей
`https://vpn.digital-home.site/admin?key=mysecret2026`
Вставляешь vless:// ссылку из Marzban → получаешь ссылку на 24 часа для друга.
---
*Обновлено: 01.04.2026*

View File

@@ -0,0 +1,111 @@
```
{
"log": {
"loglevel": "warning"
},
"routing": {
"rules": [
{
"ip": [
"geoip:cloudflare"
],
"outboundTag": "DIRECT",
"type": "field"
}
]
},
"inbounds": [
{
"tag": "VLESS_REALITY",
"listen": "0.0.0.0",
"port": 2083,
"protocol": "vless",
"settings": {
"clients": [],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"show": false,
"dest": "www.apple.com:443",
"xver": 0,
"serverNames": [
"www.apple.com"
],
"privateKey": "sIiJLOrd5kisiC4Fx3OXBKqEinrtYa5vt4CalThTvkI",
"shortIds": [
"fb8382e98f461945",
"a1b2c3d4"
]
}
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "DIRECT"
},
{
"protocol": "blackhole",
"tag": "BLOCK"
}
]
}
```
```
{
"log": {
"loglevel": "warning"
},
"routing": {
"rules": [
{
"ip": [
"geoip:private"
],
"outboundTag": "BLOCK",
"type": "field"
}
]
},
"inbounds": [
{
"tag": "Shadowsocks TCP",
"listen": "0.0.0.0",
"port": 1080,
"protocol": "shadowsocks",
"settings": {
"clients": [],
"network": "tcp,udp"
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "DIRECT"
},
{
"protocol": "blackhole",
"tag": "BLOCK"
}
]
}
```
```
id leadNumber creator
```

303
Без названия.md Normal file
View File

@@ -0,0 +1,303 @@
cat .openclaw/openclaw.json  8.07s   :daniil-openclaw 
{
"meta": {
"lastTouchedVersion": "2026.3.24",
"lastTouchedAt": "2026-04-04T21:30:41.300Z"
},
"env": {
"MOONSHOT_API_KEY": "sk-TOKEN"
},
"wizard": {
"lastRunAt": "2026-03-31T11:19:16.350Z",
"lastRunVersion": "2026.3.24",
"lastRunCommand": "doctor",
"lastRunMode": "local"
},
"auth": {
"profiles": {
"anthropic:default": {
"provider": "anthropic",
"mode": "token"
}
}
},
"acp": {
"enabled": true,
"dispatch": {
"enabled": true
},
"backend": "acpx",
"defaultAgent": "claude",
"allowedAgents": [
"codex",
"claude",
"opencode",
"gemini"
],
"stream": {
"coalesceIdleMs": 5000,
"maxChunkChars": 16000
},
"runtime": {
"ttlMinutes": 120
}
},
"models": {
"providers": {
"moonshot": {
"baseUrl": "https://api.moonshot.ai/v1",
"apiKey": "${MOONSHOT_API_KEY}",
"api": "openai-completions",
"models": [
{
"id": "kimi-k2.5",
"name": "Kimi K2.5",
"reasoning": false,
"input": [
"text",
"image"
],
"contextWindow": 262144,
"maxTokens": 262144
},
{
"id": "kimi-k2-thinking",
"name": "Kimi K2 Thinking",
"reasoning": true,
"input": [
"text"
],
"contextWindow": 262144,
"maxTokens": 262144
}
]
}
}
},
"agents": {
"defaults": {
"model": {
"primary": "anthropic/claude-sonnet-4-6",
"fallbacks": [
"anthropic/claude-haiku-4-5"
]
},
"models": {
"anthropic/claude-sonnet-4-6": {
"alias": "Sonnet 4.6"
},
"anthropic/claude-opus-4-6": {
"alias": "Opus 4.6"
},
"anthropic/claude-haiku-4-5": {
"alias": "Haiku 4.5"
},
"openai/gpt-5.4-mini": {
"alias": "GPT-5.4 Mini"
},
"openai/gpt-5.4": {
"alias": "GPT-5.4"
},
"openai/gpt-5.4-pro": {
"alias": "GPT-5.4 Pro"
},
"moonshot/kimi-k2.5": {
"alias": "Kimi K2.5"
}
},
"workspace": "/home/daniil/.openclaw/workspace",
"compaction": {
"mode": "safeguard"
},
"maxConcurrent": 4,
"subagents": {
"maxConcurrent": 8
}
},
"list": [
{
"id": "main",
"default": true,
"name": "Cosmo",
"workspace": "/home/daniil/.openclaw/workspace"
},
{
"id": "wife",
"name": "Ассистент",
"workspace": "/home/daniil/.openclaw/workspace-wife"
}
]
},
"tools": {
"web": {
"search": {
"enabled": true,
"provider": "brave",
"maxResults": 5
}
},
"media": {
"audio": {
"enabled": true,
"models": [
{
"provider": "groq",
"model": "whisper-large-v3-turbo"
}
]
}
},
"exec": {
"notifyOnExit": false
}
},
"bindings": [
{
"agentId": "wife",
"match": {
"channel": "telegram",
"accountId": "wife"
}
},
{
"type": "route",
"agentId": "main",
"match": {
"channel": "telegram",
"accountId": "daniil",
"peer": {
"kind": "direct",
"id": "398382229"
}
}
}
],
"messages": {
"ackReactionScope": "group-mentions",
"tts": {
"auto": "inbound",
"provider": "microsoft",
"edge": {
"enabled": true,
"voice": "ru-RU-DmitryNeural",
"lang": "ru-RU",
"outputFormat": "audio-24khz-48kbitrate-mono-mp3"
},
"microsoft": {
"enabled": true,
"voice": "ru-RU-DmitryNeural",
"lang": "ru-RU",
"outputFormat": "audio-24khz-48kbitrate-mono-mp3",
"pitch": "+0%",
"rate": "+0%"
}
}
},
"commands": {
"native": "auto",
"nativeSkills": "auto",
"restart": true,
"ownerDisplay": "raw"
},
"hooks": {
"internal": {
"enabled": true,
"entries": {
"command-logger": {
"enabled": true
},
"session-memory": {
"enabled": true
}
}
}
},
"channels": {
"telegram": {
"enabled": true,
"dmPolicy": "pairing",
"groupAllowFrom": [
"398382229"
],
"groupPolicy": "allowlist",
"streaming": "partial",
"actions": {
"reactions": true
},
"accounts": {
"daniil": {
"name": "Cosmo (Даниил)",
"dmPolicy": "pairing",
"botToken": "8527290610:TOKEN",
"allowFrom": [
"398382229"
],
"groupPolicy": "allowlist",
"streaming": "off",
"threadBindings": {
"spawnAcpSessions": false
}
},
"wife": {
"name": "Бот жены",
"dmPolicy": "allowlist",
"botToken": "8351034602:TOKEN",
"allowFrom": [
"197366320"
],
"groupPolicy": "allowlist",
"streaming": "off"
}
}
}
},
"gateway": {
"port": 18789,
"mode": "local",
"bind": "lan",
"controlUi": {
"allowedOrigins": [
"http://localhost:18789",
"http://127.0.0.1:18789",
"http://192.168.31.103:18789",
"http://192.168.31.95:18789"
]
},
"auth": {
"mode": "token",
"token": "TOKEN"
},
"tailscale": {
"mode": "off",
"resetOnExit": false
}
},
"skills": {
"install": {
"nodeManager": "npm"
}
},
"plugins": {
"entries": {
"telegram": {
"enabled": true
},
"brave": {
"enabled": true,
"config": {
"webSearch": {
"apiKey": "KEY"
}
}
},
"acpx": {
"enabled": true,
"config": {
"permissionMode": "approve-all",
"command": "/home/daniil/bin/acpx-wrapper.sh",
"expectedVersion": "any"
}
}
}
}
}

View File

@@ -0,0 +1,137 @@
# Ultrahuman Ring PRO — Анализ дизайна и UX
> Источник: https://www.ultrahuman.com/global/ring-pro/
> Сохранено: 2026-04-02
> Цель: вдохновение для редизайна Pulse App
---
## 🎨 Визуальный дизайн сайта
### Общий стиль
- **Тёмная тема** как основная — почти чёрный фон (`#0a0a0a`, `#111`), текст белый
- **Акцентный цвет** — насыщенный тёмно-зелёный / teal (`#00c896` примерно), используется для иконок, индикаторов, меток состояния
- **Типографика** — крупные, жирные заголовки (видимо sans-serif, похоже на Inter/Neue Haas), огромный кегль на hero-секциях
- **Контраст** — очень высокий, метрики выделяются большими цифрами на тёмном фоне
### Фотографии и визуалы
- Телефон в руке — реалистичные 3D-рендеры, не скриншоты
- Фоновые фото людей в движении — размытые, тёмные, атмосферные (оранжевые, синие градиенты)
- Каждая функция — отдельная «карточка» с реальным скриншотом приложения + фото/паттерн на фоне
- Использование градиентных blob-овалов как фоновых элементов (зелёные, синие, розовые свечения)
### Компоненты
- **Таб-бар** внизу экрана телефона — горизонтальный, полупрозрачный тёмный фон, активный таб белый жирный
- **Карточки метрик** — скруглённые углы, плотный padding, маленький лейбл сверху + большое число
- **Индикаторы статуса** — цветные теги (зелёный «Excellent», красный «Needs attention»)
- **Мини-графики** — sparkline прямо в карточке, тонкие линии
- **Прогресс-бар** — тонкий, цветной (зелёный/красный)
---
## 📱 UX и структура приложения
### Навигация
Четыре основных раздела в таб-баре:
| Таб | Содержимое |
|-----|-----------|
| **Sleep** | Sleep Index, стадии сна, REM/Deep/Light, детальный timeline |
| **Vitals** | HR, RHR, HRV, VO2 Max, Temp, Cardio Age |
| **PowerPlugs** | Маркетплейс плагинов (Women's Health, Respiratory, Heart) |
| **Longevity** | Ultra Age = Brain Age + Pulse Age + Blood Age |
### Ключевые экраны
#### Dashboard / Longevity
- Центральный элемент — **большое число** (возраст: 32, с маркером "+3 years older")
- Под ним — объяснение одной фразой: *"You're currently aging at a faster aging pace than expected for your age"*
- Contributors: три субметрики (Brain Age 32, Pulse Age 28, Blood Age 31) с иконками
#### Sleep
- Score крупно (74), под ним timeline-график сна по стадиям
- Стадии: Awake, REM, Light Sleep, Deep Sleep — цветовая кодировка
- Мини-гистограмма активности по ночи
#### Vitals
- Сетка карточек 2×n
- Каждая карточка: лейбл + значение + delta (`+2`) + статус (Within typical range) + мини-sparkline
- Метрики: Heart Rate, Resting HR, HRV, VO2 Max, Temp Deviation, Cardio Age
#### PowerPlugs
- App Store-стиль: карточки с gradient-обложками
- Каждый плагин: иконка + название + категория + кнопка Get / Installed
---
## 💡 Фичи для вдохновения в Pulse
### Что можно взять напрямую
| Идея | Где в Pulse | Сложность |
|------|------------|-----------|
| **Readiness Score как центральный элемент** — большое число, одна фраза-объяснение | Health Dashboard | Низкая — данные уже есть |
| **Contributors под скором** — разбивка на 3 субметрики (сон, HRV, RHR) | Health Dashboard | Низкая |
| **Цветовые статусы** — Excellent / Good / Needs attention | Везде | Низкая |
| **Sparkline в карточке** — мини-график прямо рядом с числом | Health, Финансы | Средняя |
| **Tab-bar снизу** — Sleep / Vitals / Habits / Finance | Главная навигация | Низкая |
| **Timeline сна** — гистограмма по часам с фазами | Sleep раздел | Средняя |
| **Delta значений**`+2 bpm vs yesterday` рядом с числом | Все метрики | Низкая |
### Концепции посложнее
| Идея | Описание | Сложность |
|------|---------|-----------|
| **"Biological Age" аналог** | Индекс долгосрочного здоровья на основе сна + HRV + активности | Высокая |
| **PowerPlugs аналог** | Маркетплейс трекеров/модулей (привычки, финансы, здоровье) | Высокая |
| **AI-объяснения** (как Jade) | *"Low glymphatic clearance is slowing mental recovery"* — причина + рекомендация | Высокая |
| **Stress Rhythm** | Трекинг стресса по HRV в течение дня | Высокая (нет датчика) |
---
## 🖌️ Дизайн-система для адаптации в Pulse
### Цвета
```
Фон: #0d0d0d — #111111
Карточки: #1a1a1a — #1e1e1e
Акцент: #00c896 (teal/зелёный) — уже близко к нашему Deep Teal
Хорошо: #00c896 green
Внимание: #ff4d4d red
Нейтральный: #888888 gray
Текст: #ffffff primary, #aaaaaa secondary
```
### Типографика
- Заголовки: очень крупные (48px+), жирные, Inter или аналог
- Метрики: 3248px, bold
- Лейблы: 1012px, uppercase, letter-spacing
- Описание: 14px, regular, серый
### Карточки
```
border-radius: 1620px
padding: 1620px
background: rgba(255,255,255,0.05) или #1e1e1e
```
---
## 📋 Приоритетный план для Pulse
**Фаза 1 (быстрые wins):**
1. Редизайн Health Dashboard — большой Readiness Score + 3 contributors
2. Добавить цветовые статусы к метрикам (Excellent / Needs attention)
3. Delta значений (`+2 vs yesterday`) везде
**Фаза 2 (средний срок):**
4. Sparklines в карточках метрик
5. Timeline-график сна по фазам
6. Tab-bar навигация (Sleep / Vitals / Habits / Finance)
**Фаза 3 (амбициозно):**
7. AI-интерпретации метрик (Cosmo объясняет что значит HRV = 45)
8. "Pulse Age" — агрегированный индекс здоровья
---
*Сохранено Cosmo, 02.04.2026*

View File

@@ -1,12 +0,0 @@
| | 100 | 200 | 300 | 400 | 500 |
| --------------- | ------------------ | ------------------ | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| Песни наоборот | Агутин - Аэропорты | Дима Билан - Держи | Звери - Районы кварталы | Корни - Ты узнаешь ее | Максим - Знаешь ли ты |
| Продолжи песню | Мы увидим сзади | Из ярких лампочек | Все твои слова | Силы не жалей | Что любят гламур |
| Вопросы от Дани | Она забыла его имя | Настольный теннис | Винни-пух | Кошка | 25 |
| Сумерки | Белла | Эдвард Каллен | Бейсбол | В балетную студию в Фениксе | Что она упала с лестницы и вылетела через окно |
| Чей плейлист | Ксюша | Даша | Света | Юля Шубина | Юля Мосина |
| Поездки | 25 тысяч шагов | Изразцы | Альберт | Княгиня Ольга | 922 |
| Факты о нас | 2 месяца | Даша Неберова | 1 год и 7 месяцев | Животные | Аллергия на текилу |
| Универ | 1832 | Норильск | Информационные технологии графического проектирования | Препод по философии (Гурьев Евгений Павлович) | Разумнова Елена Альбертовна |
| Профессия | | Канальный | Б.Н. Ельцин | Комитет по государственному контролю, использованию и охране памятников истории и культуры Санкт-Петербурга | 4 |
| Наши встречи | Уэнсдей | Август 2023 года | Учебник по металлическим конструкциям | Для смысла | Вынуть батарейки из Дашиных часов в гостиной |

View File

@@ -0,0 +1,337 @@
# pulse-api — Архитектура
**Репозиторий:** `https://git.digital-home.site/daniil/pulse-api`
**Go module:** `github.com/daniil/homelab-api`
**URL:** `https://api.digital-home.site`
**Dev:** `http://192.168.31.60:8081`
## Общая архитектура
Классический Go REST API с разделением на слои:
```
cmd/api/main.go ← точка входа, роутер, инициализация
internal/
config/ ← загрузка env-переменных
repository/ ← работа с БД (SQL-запросы)
service/ ← бизнес-логика
handler/ ← HTTP-хендлеры (request/response)
model/ ← структуры данных (Go structs + JSON)
middleware/ ← JWT-аутентификация
bot/ ← Telegram бот
scheduler/ ← cron-задачи (напоминания)
```
**Стек:**
- Router: `go-chi/chi v5`
- ORM: `jmoiron/sqlx` (raw SQL + named queries)
- БД: PostgreSQL 16
- JWT: `golang-jwt/jwt v5`
- Telegram: `go-telegram-bot-api v5`
- Cron: `robfig/cron v3`
- Email: Resend API (`service/email.go`)
- Крипто: `golang.org/x/crypto` (bcrypt для паролей)
## Структура папок
```
pulse-api/
├── cmd/api/main.go # Точка входа: роутер, DI, запуск
├── internal/
│ ├── bot/
│ │ ├── bot.go # Инициализация, Start(), SendMessage()
│ │ └── handlers.go # Команды и callback кнопки
│ ├── config/
│ │ └── config.go # Config struct + Load() из env
│ ├── handler/
│ │ ├── auth.go # Register, Login, Refresh, Me, VerifyEmail...
│ │ ├── tasks.go # CRUD задач + complete/uncomplete
│ │ ├── habits.go # CRUD привычек + логи + статистика
│ │ ├── habit_freeze.go # Заморозка привычек
│ │ ├── finance.go # Категории и транзакции финансов
│ │ ├── savings.go # Накопления (категории, участники, планы)
│ │ ├── interest.go # Начисление процентов
│ │ ├── profile.go # Профиль пользователя
│ │ └── health.go # GET /health
│ ├── middleware/
│ │ └── auth.go # JWT Bearer middleware
│ ├── model/
│ │ ├── user.go # User, RegisterRequest, LoginRequest...
│ │ ├── task.go # Task, CreateTaskRequest...
│ │ ├── habit.go # Habit, HabitLog, HabitStats...
│ │ ├── habit_freeze.go # HabitFreeze
│ │ ├── finance.go # FinanceCategory, FinanceTransaction...
│ │ ├── savings.go # SavingsCategory, SavingsTransaction...
│ │ └── email.go # Email templates
│ ├── repository/
│ │ ├── db.go # NewDB() + RunMigrations()
│ │ ├── user.go # UserRepository
│ │ ├── task.go # TaskRepository
│ │ ├── habit.go # HabitRepository
│ │ ├── habit_freeze.go # HabitFreezeRepository
│ │ ├── finance.go # FinanceRepository
│ │ ├── savings.go # SavingsRepository
│ │ └── email_token.go # EmailTokenRepository
│ ├── service/
│ │ ├── auth.go # AuthService: register/login/JWT
│ │ ├── habit.go # HabitService
│ │ ├── task.go # TaskService
│ │ ├── finance.go # FinanceService
│ │ ├── interest.go # Начисление процентов
│ │ └── email.go # EmailService (Resend)
│ └── scheduler/
│ └── scheduler.go # Cron-напоминания через Telegram
├── docs/
│ └── SAVINGS.md
├── go.mod
├── Dockerfile
└── docker-compose.yml
```
## API Эндпоинты
### Публичные (без авторизации)
| Метод | Путь | Описание |
|-------|------|----------|
| GET | `/health` | Health check |
| POST | `/auth/register` | Регистрация: `{email, username, password}` |
| POST | `/auth/login` | Логин: `{email, password}``{access_token, refresh_token, user}` |
| POST | `/auth/refresh` | Обновление токена: `{refresh_token}` |
| POST | `/auth/verify-email` | Подтверждение email: `{token}` |
| POST | `/auth/resend-verification` | Повторная отправка: `{email}` |
| POST | `/auth/forgot-password` | Сброс пароля: `{email}` |
| POST | `/auth/reset-password` | Новый пароль: `{token, new_password}` |
### Авторизованные (Bearer JWT)
#### Аутентификация/Профиль
| Метод | Путь | Описание |
|-------|------|----------|
| GET | `/auth/me` | Текущий пользователь |
| PUT | `/auth/me` | Обновить профиль |
| PUT | `/auth/password` | Сменить пароль: `{old_password, new_password}` |
| GET | `/profile` | Профиль |
| PUT | `/profile` | Обновить профиль |
#### Задачи
| Метод | Путь | Описание |
|-------|------|----------|
| GET | `/tasks` | Список задач. Query: `?completed=true/false` |
| GET | `/tasks/today` | Задачи на сегодня |
| POST | `/tasks` | Создать: `{title, description?, icon?, color?, due_date?, priority?, reminder_time?, is_recurring?, recurrence_type?, recurrence_interval?, recurrence_end_date?}` |
| GET | `/tasks/{id}` | Получить задачу |
| PUT | `/tasks/{id}` | Обновить задачу |
| DELETE | `/tasks/{id}` | Удалить задачу |
| POST | `/tasks/{id}/complete` | Отметить выполненной |
| POST | `/tasks/{id}/uncomplete` | Снять отметку |
#### Привычки
| Метод | Путь | Описание |
|-------|------|----------|
| GET | `/habits` | Список привычек |
| POST | `/habits` | Создать: `{name, description?, color?, icon?, frequency, target_days?, target_count?, reminder_time?, start_date?}` |
| GET | `/habits/{id}` | Получить привычку |
| PUT | `/habits/{id}` | Обновить |
| DELETE | `/habits/{id}` | Удалить |
| POST | `/habits/{id}/log` | Отметить: `{date?, count?, note?}` |
| GET | `/habits/{id}/logs` | История отметок |
| DELETE | `/habits/{id}/logs/{logId}` | Удалить отметку |
| GET | `/habits/stats` | Общая статистика |
| GET | `/habits/{id}/stats` | Статистика привычки |
| GET | `/habits/{id}/freezes` | Заморозки привычки |
| POST | `/habits/{id}/freezes` | Создать заморозку |
| DELETE | `/habits/{id}/freezes/{freezeId}` | Удалить заморозку |
#### Финансы
| Метод | Путь | Описание |
|-------|------|----------|
| GET | `/finance/categories` | Категории расходов/доходов |
| POST | `/finance/categories` | Создать: `{name, emoji?, type, budget?, color?, sort_order?}` |
| PUT | `/finance/categories/{id}` | Обновить |
| DELETE | `/finance/categories/{id}` | Удалить |
| GET | `/finance/transactions` | Транзакции. Query: `?month=&year=` |
| POST | `/finance/transactions` | Создать: `{category_id, type, amount, description?, date}` |
| PUT | `/finance/transactions/{id}` | Обновить |
| DELETE | `/finance/transactions/{id}` | Удалить |
| GET | `/finance/summary` | Сводка: баланс, доходы, расходы, по категориям |
| GET | `/finance/analytics` | Аналитика: тренды по месяцам |
#### Накопления
| Метод | Путь | Описание |
|-------|------|----------|
| GET | `/savings/categories` | Категории накоплений |
| POST | `/savings/categories` | Создать категорию |
| GET | `/savings/categories/{id}` | Получить |
| PUT | `/savings/categories/{id}` | Обновить |
| DELETE | `/savings/categories/{id}` | Удалить |
| GET | `/savings/categories/{id}/members` | Участники |
| POST | `/savings/categories/{id}/members` | Добавить участника |
| DELETE | `/savings/categories/{id}/members/{userId}` | Удалить участника |
| GET | `/savings/categories/{id}/recurring-plans` | Регулярные планы |
| POST | `/savings/categories/{id}/recurring-plans` | Создать план |
| PUT | `/savings/recurring-plans/{planId}` | Обновить план |
| DELETE | `/savings/recurring-plans/{planId}` | Удалить план |
| GET | `/savings/transactions` | Транзакции накоплений |
| POST | `/savings/transactions` | Создать транзакцию |
| GET | `/savings/transactions/{id}` | Получить |
| PUT | `/savings/transactions/{id}` | Обновить |
| DELETE | `/savings/transactions/{id}` | Удалить |
| GET | `/savings/stats` | Статистика |
## Модели данных
### User
```go
type User struct {
ID int64
Email string
Username string
PasswordHash string // bcrypt, в JSON скрыто
EmailVerified bool
TelegramChatID *int64 // nullable
NotificationsEnabled bool
Timezone string
MorningReminderTime string // "09:00"
EveningReminderTime string // "21:00"
CreatedAt, UpdatedAt time.Time
}
```
### Task
```go
type Task struct {
ID, UserID int64
Title, Description string
Icon, Color string
DueDate *string // "2026-01-01"
Priority int // 1=низкий, 2=средний, 3=высокий
ReminderTime *string // "19:00"
Completed bool // производное от CompletedAt
// Повторяющиеся задачи:
IsRecurring bool
RecurrenceType *string // "daily", "weekly", "monthly"
RecurrenceInterval int
RecurrenceEndDate *string
ParentTaskID *int64
CreatedAt, UpdatedAt time.Time
}
```
### Habit
```go
type Habit struct {
ID, UserID int64
Name, Description string
Color, Icon string
Frequency string // "daily", "weekly", "custom"
TargetDays []int // дни недели (0=вс...6=сб)
TargetCount int
ReminderTime *string // "19:00"
StartDate *string
IsArchived bool
CreatedAt, UpdatedAt time.Time
}
type HabitLog struct {
ID, HabitID, UserID int64
Date time.Time
Count int
Note string
CreatedAt time.Time
}
```
### FinanceCategory / FinanceTransaction
```go
type FinanceCategory struct {
ID, UserID int64
Name, Emoji string
Type string // "income" | "expense"
Budget *float64
Color string
SortOrder int
CreatedAt time.Time
}
type FinanceTransaction struct {
ID, UserID, CategoryID int64
Type string // "income" | "expense"
Amount float64
Description string
Date time.Time
CreatedAt time.Time
CategoryName, CategoryEmoji string // из JOIN
}
```
## Аутентификация
- **JWT HS256** с двумя типами токенов: `access` (короткий) и `refresh` (длинный)
- Middleware `Authenticate` парсит `Authorization: Bearer <token>`, проверяет `type == "access"`
- UserID извлекается из claims и помещается в context: `GetUserID(ctx)`
- Пароли хешируются bcrypt
- Email-верификация при регистрации через Resend API
- Password reset — одноразовые токены в таблице `email_tokens`
## Telegram Бот
**Команды:**
| Команда | Действие |
|---------|---------|
| `/start` | Показать Chat ID (для привязки к аккаунту Pulse) |
| `/tasks` | Список задач на сегодня с inline-кнопками |
| `/habits` | Привычки на сегодня с inline-кнопками |
| `/done <id>` или `/done_<id>` | Отметить задачу выполненной |
| `/check <id>` или `/check_<id>` | Отметить привычку |
| `/help` | Справка |
**Callback-кнопки:**
- `donetask_<id>` — выполнить задачу
- `deltask_<id>` — удалить задачу
- `checkhabit_<id>` — отметить привычку сегодня
- `checkhabit_<id>_yesterday` — отметить привычку за вчера
**Привязка:** пользователь вводит `/start`, получает Chat ID, вставляет его в настройки Pulse → `PUT /profile {telegram_chat_id: ...}`
## Scheduler (cron-напоминания)
`internal/scheduler/scheduler.go` — использует `robfig/cron`:
- Утренние напоминания (время из настроек пользователя)
- Вечерние напоминания
- Напоминания о задачах по `reminder_time`
- Напоминания о привычках по `reminder_time`
## Конфигурация (env переменные)
| Переменная | Описание | Default |
|-----------|----------|---------|
| `DATABASE_URL` | PostgreSQL DSN | `postgres://homelab:homelab@db:5432/homelab` |
| `JWT_SECRET` | Секрет для JWT | `change-me-in-production` |
| `PORT` | Порт сервера | `8080` |
| `RESEND_API_KEY` | API ключ Resend (email) | — |
| `FROM_EMAIL` | Email отправителя | `noreply@digital-home.site` |
| `FROM_NAME` | Имя отправителя | `Homelab` |
| `APP_URL` | Публичный URL приложения | `https://api.digital-home.site` |
| `TELEGRAM_BOT_TOKEN` | Токен Telegram бота | — |
## Где искать что
| Задача | Файл |
|--------|------|
| Добавить новый эндпоинт | `handler/<domain>.go` + роут в `cmd/api/main.go` |
| Изменить модель/таблицу | `model/<domain>.go` + `repository/db.go` (migrations) |
| Логика уведомлений | `internal/scheduler/scheduler.go` |
| Telegram команды | `internal/bot/handlers.go` |
| Финансы (категории/транзакции) | `handler/finance.go`, `service/finance.go`, `repository/finance.go` |
| Привычки | `handler/habits.go`, `service/habit.go`, `repository/habit.go` |
| Задачи | `handler/tasks.go`, `service/task.go`, `repository/task.go` |
| Накопления | `handler/savings.go`, `repository/savings.go` |
| Email отправка | `service/email.go` |
| JWT/Auth | `service/auth.go`, `middleware/auth.go` |
| Конфиг | `config/config.go` |

View File

@@ -0,0 +1,263 @@
# pulse-web — Архитектура
**Репозиторий:** `https://git.digital-home.site/daniil/pulse-web`
**URL:** `https://pulse.digital-home.site`
**Dev:** `http://192.168.31.60:5174`
**Storybook:** `http://192.168.31.60:6006`
## Общая архитектура
React SPA (Single Page Application):
```
src/
api/ ← API-функции (axios, по доменам)
store/ ← State management (Zustand)
contexts/ ← React Context (тема)
pages/ ← Страницы (маршруты)
components/ ← Переиспользуемые компоненты
main.jsx ← Точка входа (BrowserRouter + ThemeContext)
App.jsx ← Роутер (Routes/Route)
index.css ← Глобальные стили (Tailwind)
```
**Стек:**
- Framework: React 18
- Bundler: Vite 5
- Роутинг: React Router DOM 6
- State: Zustand 4
- HTTP: Axios (с interceptors для JWT refresh)
- UI: Tailwind CSS 3
- Анимации: Framer Motion 11
- Иконки: Lucide React
- Графики: Recharts 2
- Утилиты дат: date-fns 3
- Компонент-либа: Storybook 8
- Тесты: Vitest + Testing Library
## Структура папок
```
pulse-web/
├── src/
│ ├── api/
│ │ ├── client.js # Axios instance + JWT interceptor
│ │ ├── auth.js # (в store/auth.js)
│ │ ├── tasks.js # tasksApi: list, today, create, complete...
│ │ ├── habits.js # habitsApi: list, create, log, stats...
│ │ ├── finance.js # financeApi: categories, transactions, summary
│ │ ├── savings.js # savingsApi: categories, transactions, stats
│ │ └── profile.js # profileApi: get, update
│ ├── store/
│ │ └── auth.js # useAuthStore (Zustand): user, login, logout
│ ├── contexts/
│ │ └── ThemeContext.jsx # ThemeProvider: light/dark, localStorage
│ ├── pages/
│ │ ├── Home.jsx # Главная страница (дашборд)
│ │ ├── Tracker.jsx # Трекер (таб: привычки/задачи/статистика)
│ │ ├── Habits.jsx # Страница привычек (встраивается в Tracker)
│ │ ├── Tasks.jsx # Страница задач (встраивается в Tracker)
│ │ ├── Stats.jsx # Статистика (встраивается в Tracker)
│ │ ├── Finance.jsx # Финансы (таб: обзор/транзакции/аналитика/категории)
│ │ ├── Savings.jsx # Накопления
│ │ ├── Settings.jsx # Настройки пользователя
│ │ ├── Login.jsx # Вход
│ │ ├── Register.jsx # Регистрация
│ │ ├── ForgotPassword.jsx # Сброс пароля
│ │ ├── ResetPassword.jsx # Новый пароль (по токену из email)
│ │ └── VerifyEmail.jsx # Подтверждение email
│ ├── components/
│ │ ├── Navigation.jsx # Нижняя навигация (fixed bottom)
│ │ ├── CreateTaskModal.jsx
│ │ ├── EditTaskModal.jsx
│ │ ├── CreateHabitModal.jsx
│ │ ├── EditHabitModal.jsx
│ │ ├── LogHabitModal.jsx
│ │ └── finance/
│ │ ├── FinanceDashboard.jsx # Обзор месяца
│ │ ├── TransactionList.jsx # Список транзакций
│ │ ├── FinanceAnalytics.jsx # Графики трендов
│ │ ├── CategoriesManager.jsx # Управление категориями
│ │ └── AddTransactionModal.jsx
│ ├── App.jsx # Routes + ProtectedRoute/PublicRoute
│ ├── main.jsx # ReactDOM.render + Providers
│ └── index.css # Tailwind + кастомные стили
├── public/
├── package.json
├── vite.config.js
├── tailwind.config.js
├── nginx.conf
└── Dockerfile
```
## Страницы / Роуты
| Путь | Компонент | Защита | Описание |
|------|-----------|--------|----------|
| `/login` | `Login` | Public only | Форма входа |
| `/register` | `Register` | Public only | Форма регистрации |
| `/forgot-password` | `ForgotPassword` | Public only | Запрос сброса пароля |
| `/verify-email` | `VerifyEmail` | Нет | Подтверждение email по токену |
| `/reset-password` | `ResetPassword` | Нет | Установка нового пароля |
| `/` | `Home` | Protected | Главная: дашборд |
| `/tracker` | `Tracker` | Protected | Трекер привычек/задач/статистики |
| `/habits` | → `/tracker` | Protected | Редирект на трекер |
| `/tasks` | → `/tracker` | Protected | Редирект на трекер |
| `/stats` | → `/tracker` | Protected | Редирект на трекер |
| `/savings` | `Savings` | Protected | Накопления |
| `/settings` | `Settings` | Protected | Настройки аккаунта |
| `*` | → `/` | — | Любой неизвестный → главная |
### Tracker (вкладки)
`/tracker` содержит 3 вкладки:
1. **Привычки**`Habits` компонент
2. **Задачи**`Tasks` компонент
3. **Статистика**`Stats` компонент
### Finance (вкладки)
`/finance` (доступна через роутер если добавить) содержит 4 вкладки:
1. **Обзор**`FinanceDashboard`
2. **Транзакции**`TransactionList`
3. **Аналитика**`FinanceAnalytics`
4. **Категории**`CategoriesManager`
> ⚠️ Страница Finance рендерится, но **нет роута** в App.jsx. Доступ только если добавить `<Route path="/finance">`.
## Основные компоненты
| Компонент | Файл | Назначение |
|-----------|------|------------|
| `Navigation` | components/Navigation.jsx | Нижняя навбар (Главная, Трекер, Накопления, Настройки). Показывает Finance только для `user.id === 1` (owner) |
| `ProtectedRoute` | App.jsx | Редиректит на `/login` если не авторизован |
| `PublicRoute` | App.jsx | Редиректит на `/` если уже авторизован |
| `FinanceDashboard` | finance/ | Обзор месяца: баланс, доходы/расходы, по категориям, дневной график |
| `TransactionList` | finance/ | Список транзакций с фильтрацией |
| `FinanceAnalytics` | finance/ | Recharts: тренды по месяцам |
| `CategoriesManager` | finance/ | CRUD категорий |
| `AddTransactionModal` | finance/ | Модал добавления транзакции |
| `CreateTaskModal` | components/ | Создание задачи |
| `EditTaskModal` | components/ | Редактирование задачи |
| `CreateHabitModal` | components/ | Создание привычки |
| `LogHabitModal` | components/ | Отметка привычки |
## API вызовы
### Axios Client (`src/api/client.js`)
```js
const api = axios.create({ baseURL: VITE_API_URL })
// Request interceptor: добавляет Bearer токен из localStorage
api.interceptors.request Authorization: Bearer <access_token>
// Response interceptor: при 401 делает refresh и повторяет запрос
api.interceptors.response POST /auth/refresh обновляет tokens в localStorage
```
### API модули
```js
// tasks.js
tasksApi.list(completed?) GET /tasks
tasksApi.today() GET /tasks/today
tasksApi.create(data) POST /tasks
tasksApi.complete(id) POST /tasks/{id}/complete
tasksApi.uncomplete(id) POST /tasks/{id}/uncomplete
tasksApi.update(id, data) PUT /tasks/{id}
tasksApi.delete(id) DELETE /tasks/{id}
// habits.js
habitsApi.list() GET /habits
habitsApi.create(data) POST /habits
habitsApi.log(id, data) POST /habits/{id}/log
habitsApi.stats() GET /habits/stats
habitsApi.habitStats(id) GET /habits/{id}/stats
// finance.js
financeApi.getCategories() GET /finance/categories
financeApi.createCategory(data) POST /finance/categories
financeApi.getTransactions(m, y) GET /finance/transactions?month=&year=
financeApi.createTransaction(data) POST /finance/transactions
financeApi.getSummary(m, y) GET /finance/summary
financeApi.getAnalytics() GET /finance/analytics
// savings.js
savingsApi.getCategories() GET /savings/categories
savingsApi.createCategory(data) POST /savings/categories
savingsApi.getTransactions() GET /savings/transactions
savingsApi.getStats() GET /savings/stats
// profile.js
profileApi.get() GET /profile
profileApi.update(data) PUT /profile
```
## State Management
**Zustand** — единственный store: `src/store/auth.js`
```js
useAuthStore = {
user: null | User,
isLoading: boolean,
isAuthenticated: boolean,
initialize() // Вызывается в App.jsx useEffect: GET /auth/me
login(email, password) // POST /auth/login, сохраняет tokens
register(email, username, password)
logout() // Чистит localStorage + state
}
```
**React Context:**
- `ThemeContext` (`contexts/ThemeContext.jsx`) — dark/light mode, сохраняется в localStorage
**Нет Redux / React Query** — данные загружаются локально в компонентах через `useState + useEffect`.
## Основные зависимости
| Пакет | Версия | Назначение |
|-------|--------|------------|
| react | 18.2 | UI framework |
| react-router-dom | 6.22 | Роутинг |
| zustand | 4.5 | State management |
| axios | 1.6 | HTTP клиент |
| tailwindcss | 3.4 | CSS utility framework |
| framer-motion | 11 | Анимации |
| lucide-react | 0.312 | Иконки |
| recharts | 2.12 | Графики |
| date-fns | 3.3 | Утилиты дат |
| clsx | 2.1 | Условные классы |
| storybook | 8.5 | UI компонент-браузер (dev) |
| vitest | 4 | Тесты |
## Конфигурация
| Env переменная | Описание | Default |
|---------------|----------|---------|
| `VITE_API_URL` | URL backend API | `https://api.digital-home.site` |
## Где искать что
| Задача | Файл |
|--------|------|
| **Новая страница** | `src/pages/NewPage.jsx` + роут в `App.jsx` + ссылка в `Navigation.jsx` |
| **Новый компонент** | `src/components/NewComponent.jsx` |
| **Новый API вызов** | `src/api/<domain>.js` (добавить метод) |
| **Финансы: UI** | `src/pages/Finance.jsx`, `src/components/finance/` |
| **Финансы: API** | `src/api/finance.js` |
| **Привычки: UI** | `src/pages/Habits.jsx`, `CreateHabitModal`, `LogHabitModal` |
| **Привычки: API** | `src/api/habits.js` |
| **Задачи: UI** | `src/pages/Tasks.jsx`, `CreateTaskModal`, `EditTaskModal` |
| **Задачи: API** | `src/api/tasks.js` |
| **Авторизация** | `src/store/auth.js`, `src/pages/Login.jsx` |
| **Глобальные стили** | `src/index.css` + `tailwind.config.js` |
| **Темная тема** | `src/contexts/ThemeContext.jsx` |
| **Нижняя навигация** | `src/components/Navigation.jsx` |
## Заметки
- `Finance` страница не добавлена в роутер и навигацию для обычных пользователей — только для owner (id=1)
- Legacy роуты `/habits`, `/tasks`, `/stats` → редиректят на `/tracker`
- Токены хранятся в `localStorage`: `access_token`, `refresh_token`
- Auto-refresh токена при 401 ответе (в axios interceptor)

View File

@@ -0,0 +1,112 @@
# Сервисы VM 192.168.31.60
Все Docker-сервисы развёрнуты в `/opt/digital-home/` на VM Сервисы.
Общая сеть: `services_proxy` (создана в `services/docker-compose.yml`).
Внешний трафик: Nginx Proxy Manager → домены `*.digital-home.site`.
## Сводная таблица
| Сервис | Папка | Домен | Порты (внешние) | Статус |
|--------|-------|-------|-----------------|--------|
| Nginx Proxy Manager | services/ | — (точка входа) | 80, 81, 443 | ✅ Up |
| Gitea | gitea/ | git.digital-home.site | — (NPM) | ✅ Up |
| Gitea Runner | gitea-runner/ | — | — | ✅ Up |
| Homepage | homepage/ | home.digital-home.site | — (NPM) | ✅ Up |
| Jellyfin | media/ | — | — (NPM) | ✅ Up |
| qBittorrent | media/ | — | 6881 | ❌ Stopped |
| Nextcloud | nextcloud/ | cloud.digital-home.site | 5433 (db) | ✅ Up |
| Immich | photo/ | — | — (NPM) | ✅ Up |
| Portainer | portainer/ | portainer.digital-home.site | — (NPM) | ✅ Up |
| Uptime Kuma | uptime-kuma/ | — | — (NPM) | ✅ Up |
| Vaultwarden | vault/ | vault.digital-home.site | — (NPM) | ✅ Up |
| Vikunja | vikunja/ | tasks.digital-home.site | — (NPM) | ✅ Up |
| Menu Bot | bots/menu/ | — | — | ❓ Unknown |
| Review Bot | review-bot/ | — | 3300 | ✅ Up |
| Cosmo Studio | cosmo-studio/ | — | — (NPM) | ✅ Up |
| Pulse API | homelab-api/ | api.digital-home.site | 8081 (dev) | ✅ Up |
| Pulse Web | pulse-web/ | pulse.digital-home.site | 5174 (dev) | ✅ Up |
| Storybook | storybook/ | — | 6006 | ✅ Up |
| Health Webhook | health-webhook/ | health.digital-home.site | 3200 | ✅ Up |
| IT Tools | it-tools/ | — | — (NPM) | ✅ Up |
| Savings | savings/ | — | — (NPM) | ❌ Stopped |
| AdventureLog | adventurelog/ | — | — | ❌ Stopped |
| LangLearn | langlearn/ | — | — | ❌ Stopped |
| Lingua Learn | lingua-learn/ | — | — | ❌ Stopped |
| My Game (Своя Игра) | my-game/ | — | — | ❌ Stopped |
| Japan App | japan-app/ | — | — | ❌ Stopped |
| VPN Invite | vpn-invite/ | — | 3500 | ✅ Up |
| VPN Router | vpn-router/ | — | host network | ❌ Stopped |
| Webhook Deploy | webhook-deploy/ | — | 9000 | ❓ Unknown |
## Запущенные сервисы (docker ps)
Статус на момент документирования (02.04.2026):
```
homelab-api Up 19 hours
vpn-invite Up 21 hours
cosmo-studio (x2) Up 3 days
uptime-kuma Up 5 days (healthy)
jellyfin Up 6 days (healthy)
gitea-runner Up 6 days
review-bot Up 6 days
health-webhook Up 7 days
pulse-web Up 12 days
pulse-web-dev Up 4 weeks
pulse-api-dev Up 4 weeks
storybook Up 4 weeks
nginx_proxy_manager Up 26 hours
homelab-db Up 4 weeks (healthy)
it-tools Up 4 weeks
homepage Up 4 weeks (healthy)
immich_server Up 4 weeks (healthy)
immich_redis Up 4 weeks
immich_postgres Up 4 weeks
immich_ml Up 4 weeks (healthy)
vikunja Up 4 weeks
vikunja_db Up 4 weeks
vaultwarden Up 4 weeks (healthy)
portainer Up 4 weeks
nextcloud_app Up 4 weeks
nextcloud_db Up 4 weeks
nextcloud_redis Up 4 weeks
gitea Up 4 weeks
```
## Архитектура сети
```
Интернет
Nginx Proxy Manager (80/443)
↓ (services_proxy network)
┌───────────────────────────────┐
Все сервисы в одной сети │
│ services_proxy │
│ │
│ git.* → gitea:3000 │
│ home.* → homepage:3000 │
│ cloud.* → nextcloud_app:80 │
│ vault.* → vaultwarden:80 │
│ tasks.* → vikunja:3456 │
│ portainer.* → portainer:9000 │
│ api.* → homelab-api:8080 │
│ pulse.* → pulse-web:80 │
│ health.* → health-webhook:3200│
└───────────────────────────────┘
```
## Паттерн добавления сервиса
```bash
mkdir /opt/digital-home/<name>
cd /opt/digital-home/<name>
# docker-compose.yml с сетью:
networks:
services_proxy:
external: true
docker compose up -d
# Добавить proxy host в NPM UI (порт 81)
```

View File

@@ -0,0 +1,38 @@
# AdventureLog
## Назначение
Приложение для логирования путешествий и приключений. Ведение дневника поездок с геолокацией.
## Контейнеры
| Имя | Образ |
|-----|-------|
| adventurelog-frontend | ghcr.io/seanmorley15/adventurelog-frontend:latest |
| adventurelog-backend | ghcr.io/seanmorley15/adventurelog-backend:latest |
| adventurelog-db | postgis/postgis:16-3.5 |
## Порты
Нет внешних портов (через NPM).
## Volumes
| Volume | Контейнер | Путь контейнера | Содержимое |
|--------|-----------|----------------|------------|
| postgres_data | adventurelog-db | /var/lib/postgresql/data | БД PostGIS |
| adventurelog_media | adventurelog-backend | /code/media/ | Медиа-файлы |
## Домен
Через NPM (не указан явно).
## Сети
- `services_proxy` (external)
- `default` (internal между frontend и backend)
## Env переменные
Из `env_file: .env` (ключи неизвестны).
## Статус
**Не запущен** (не найден в `docker ps`)
## Заметки
- Использует PostGIS (PostgreSQL с геопространственными расширениями)

View File

@@ -0,0 +1,42 @@
# Menu Bot (bots/menu)
## Назначение
Telegram-бот для отображения меню / навигации. Написан на Go.
## Контейнеры
| Имя | Образ |
|-----|-------|
| menu-bot | local build (Go) |
## Порты
Нет внешних портов.
## Volumes
| Путь хоста | Путь контейнера | Содержимое |
|-----------|----------------|------------|
| ./data | /root/data | Данные бота |
## Домен
Нет.
## Сети
Нет явной сети (использует `env_file: .env`).
## Env переменные
Из `.env` файла (ключи неизвестны — файл не читался).
## Статус
**Статус неизвестен** (не найден в `docker ps`)
## Структура проекта
```
bots/menu/
├── cmd/ # Точка входа
├── internal/ # Логика бота
├── data/ # Данные
├── Dockerfile
├── docker-compose.yml
└── go.mod
```

View File

@@ -0,0 +1,36 @@
# Cosmo Studio
## Назначение
Web-интерфейс для OpenClaw AI-ассистента (Cosmo). Bridge-сервис соединяется с OpenClaw instance, frontend предоставляет UI для взаимодействия.
## Контейнеры
| Имя | Образ |
|-----|-------|
| cosmo-studio-bridge-1 | local build (Dockerfile) |
| cosmo-studio-frontend-1 | local build (Dockerfile.frontend) |
## Порты
| Контейнер | Внутренний | Назначение |
|-----------|-----------|------------|
| bridge | 3401-3402 | WebSocket bridge |
| frontend | 80 | Web UI |
## Volumes
Нет persistent volumes (конфиг через env).
## Домен
Через NPM (не указан явно).
## Сети
- `services_proxy` (external)
- `internal` (bridge между bridge и frontend)
## Env переменные
- `OPENCLAW_URL` (ws://192.168.31.103:18789)
- `OPENCLAW_TOKEN`
- `SSH_KEY_PATH`
## Статус
**Запущен** (Up 3 days)

View File

@@ -0,0 +1,40 @@
# Gitea Actions Runner
## Назначение
CI/CD runner для выполнения Gitea Actions workflows. Запускает задачи сборки, тестирования и деплоя при push/PR в Gitea.
## Контейнеры
| Имя | Образ |
|-----|-------|
| gitea-runner | gitea-runner-runner (local build) |
## Порты
Нет внешних портов.
## Volumes
| Путь хоста | Путь контейнера | Содержимое |
|-----------|----------------|------------|
| /var/run/docker.sock | /var/run/docker.sock | Docker socket (для запуска контейнеров) |
| runner_data | /data | Данные runner'а |
| ./config.yaml | /config/config.yaml | Конфиг runner'а |
## Домен
Нет.
## Сети
- `services_proxy` (external)
## Env переменные
- `GITEA_INSTANCE_URL`
- `GITEA_RUNNER_REGISTRATION_TOKEN`
- `GITEA_RUNNER_NAME`
- `CONFIG_FILE`
## Статус
**Запущен** (Up 6 days)
## Заметки
- `privileged: true` — нужно для запуска вложенных Docker-контейнеров в workflows
- Подключается к Gitea по `http://gitea:3000`

View File

@@ -0,0 +1,47 @@
# Gitea
## Назначение
Self-hosted Git-хостинг. Хранит репозитории проектов (pulse-api, pulse-web, obsidian и другие). Поддерживает Gitea Actions для CI/CD.
## Контейнеры
| Имя | Образ |
|-----|-------|
| gitea | gitea/gitea:latest |
## Порты
| Внутренний | Протокол | Назначение |
|-----------|---------|------------|
| 3000 | HTTP | Web UI + API |
| 22 | TCP | SSH для git |
(Порты открыты только в сети, внешний доступ через NPM)
## Volumes
| Путь хоста | Путь контейнера | Содержимое |
|-----------|----------------|------------|
| ./data | /data | Репозитории, конфиги, БД (SQLite) |
| /etc/timezone | /etc/timezone | Временная зона (ro) |
| /etc/localtime | /etc/localtime | Локальное время (ro) |
## Домен
`https://git.digital-home.site`
## Сети
- `gitea_backend` (internal)
- `services_proxy` (external, для NPM)
## Env переменные
- `USER_UID`
- `USER_GID`
- `GITEA__server__DOMAIN`
- `GITEA__server__ROOT_URL`
## Статус
**Запущен** (Up 4 weeks)
## Связанные сервисы
- `gitea-runner` — CI/CD runner для Gitea Actions
- `review-bot` — AI ревью PR через webhook

View File

@@ -0,0 +1,37 @@
# Health Webhook
## Назначение
Webhook-сервис для проверки здоровья / health check инфраструктуры. Node.js сервис с JWT-авторизацией, возможно интеграция с email-уведомлениями через Resend.
## Контейнеры
| Имя | Образ |
|-----|-------|
| health-webhook | local build (Node.js) |
## Порты
| Внешний | Внутренний | Назначение |
|---------|-----------|------------|
| 3200 | 3200 | HTTP API |
## Volumes
| Путь хоста | Путь контейнера | Содержимое |
|-----------|----------------|------------|
| ./data | /app/data | Данные сервиса |
## Домен
`https://health.digital-home.site`
## Сети
- `services_proxy` (external)
## Env переменные
- `JWT_SECRET`
- `NODE_ENV`
- `RESEND_API_KEY`
- `APP_URL`
## Статус
**Запущен** (Up 7 days)

View File

@@ -0,0 +1,40 @@
# Homepage
## Назначение
Стартовая страница / дашборд домашней лаборатории. Показывает все сервисы, их статусы, виджеты (погода, календарь и т.д.).
## Контейнеры
| Имя | Образ |
|-----|-------|
| homepage | ghcr.io/gethomepage/homepage:latest |
## Порты
| Внутренний | Назначение |
|-----------|------------|
| 3000 | Web UI |
## Volumes
| Путь хоста | Путь контейнера | Содержимое |
|-----------|----------------|------------|
| ./config | /app/config | YAML-конфиги (services, widgets, bookmarks) |
| ./icons | /app/public/icons | Пользовательские иконки |
| /var/run/docker.sock | /var/run/docker.sock | Docker socket (для статусов контейнеров, ro) |
## Домен
`https://home.digital-home.site`
## Сети
- `homepage_backend` (internal)
- `services_proxy` (external, для NPM)
## Env переменные
- `PUID`
- `PGID`
- `TZ`
- `HOMEPAGE_ALLOWED_HOSTS`
## Статус
**Запущен** (Up 4 weeks, healthy)

View File

@@ -0,0 +1,31 @@
# IT Tools
## Назначение
Коллекция онлайн-инструментов для разработчиков: конверторы форматов, генераторы, кодировщики, хэши и т.д.
## Контейнеры
| Имя | Образ |
|-----|-------|
| it-tools | corentinth/it-tools:latest |
## Порты
| Внутренний | Назначение |
|-----------|------------|
| 80 | Web UI (через NPM) |
## Volumes
Нет.
## Домен
Через NPM (не указан явно).
## Сети
- `services_proxy` (external)
## Env переменные
Нет.
## Статус
**Запущен** (Up 4 weeks)

View File

@@ -0,0 +1,31 @@
# Japan App
## Назначение
PWA-гид по Японии. Содержит список мест (92+), расписание поездки, карты.
## Контейнеры
| Имя | Образ |
|-----|-------|
| japan-app | local build |
## Порты
Нет (через NPM).
## Volumes
Нет.
## Домен
Через NPM (не указан явно).
## Сети
- `services_proxy` (external)
## Env переменные
Нет.
## Статус
**Не запущен** (не найден в `docker ps`)
## Заметки
- `watchtower.enable=false` — не обновляется автоматически

View File

@@ -0,0 +1,39 @@
# LangLearn
## Назначение
Приложение для изучения языков. Go backend + React frontend с PostgreSQL.
## Контейнеры
| Имя | Образ |
|-----|-------|
| langlearn-backend | local build (Go) |
| langlearn-frontend | local build (React) |
| langlearn-db | postgres:16-alpine |
## Порты
| Контейнер | Внутренний | Назначение |
|-----------|-----------|------------|
| backend | 8080 | REST API (через NPM) |
| frontend | — | Web UI (через NPM) |
## Volumes
| Volume | Контейнер | Путь контейнера | Содержимое |
|--------|-----------|----------------|------------|
| pgdata | db | /var/lib/postgresql/data | БД |
## Домен
Через NPM (не указан явно).
## Сети
- `services_proxy` (external)
- `internal` (между backend и db)
## Env переменные
- `DATABASE_URL`
- `PORT`
## Статус
**Не запущен** (не найден в `docker ps`)

View File

@@ -0,0 +1,34 @@
# Lingua Learn
## Назначение
Приложение для изучения языков (альтернативная версия). Node.js backend + React frontend.
## Контейнеры
| Имя | Образ |
|-----|-------|
| lingua-learn-client | local build (React) |
| lingua-learn-server | local build (Node.js) |
| lingua-learn-db | postgres:16-alpine |
## Порты
Нет внешних портов (через NPM).
## Volumes
| Volume | Контейнер | Путь контейнера | Содержимое |
|--------|-----------|----------------|------------|
| postgres_data | db | /var/lib/postgresql/data | БД |
## Домен
Через NPM (не указан явно).
## Сети
- `services_proxy` (external)
## Env переменные
- `DATABASE_URL`
- `NODE_ENV`
## Статус
**Не запущен** (не найден в `docker ps`)

View File

@@ -0,0 +1,50 @@
# Media (Jellyfin + qBittorrent)
## Назначение
Медиа-стек: скачивание торрентов (qBittorrent) и стриминг медиа-контента (Jellyfin).
## Контейнеры
| Имя | Образ |
|-----|-------|
| jellyfin | jellyfin/jellyfin:latest |
| qbittorrent | lscr.io/linuxserver/qbittorrent:latest |
## Порты
| Контейнер | Внешний | Внутренний | Назначение |
|-----------|---------|-----------|------------|
| qbittorrent | 6881 | 6881 | BitTorrent TCP |
| qbittorrent | 6881/udp | 6881/udp | BitTorrent UDP |
| jellyfin | — | 8096 | Web UI (через NPM) |
| qbittorrent | — | 8080 | Web UI (через NPM) |
## Volumes
| Путь хоста | Контейнер | Путь контейнера | Содержимое |
|-----------|-----------|----------------|------------|
| ./qbittorrent/config | qbittorrent | /config | Конфиг qBittorrent |
| ./downloads | qbittorrent | /downloads | Загруженные файлы |
| ./jellyfin/config | jellyfin | /config | Конфиг Jellyfin |
| ./jellyfin/cache | jellyfin | /cache | Кэш Jellyfin |
| ./downloads | jellyfin | /data/downloads | Медиа-файлы (ro) |
| ../nextcloud/nextcloud_data/data | jellyfin | /data/nextcloud | Файлы Nextcloud (ro) |
## Домен
Через NPM (не указан явно в конфиге).
## Сети
- `media_backend` (internal)
- `services_proxy` (external)
## Env переменные
- `PUID`, `PGID`, `TZ` (оба контейнера)
- `WEBUI_PORT` (qbittorrent)
## Статус
- ✅ jellyfin: **Запущен** (Up 6 days, healthy)
- ❌ qbittorrent: **Не запущен**
## Заметки
- Jellyfin имеет доступ к файлам Nextcloud через bind mount
- Закомментированная секция GPU-транскодинга для Intel

View File

@@ -0,0 +1,41 @@
# My Game (Своя игра)
## Назначение
Веб-версия игры "Своя Игра" (аналог Jeopardy). Node.js/Express backend + React frontend + MongoDB.
## Контейнеры
| Имя | Образ |
|-----|-------|
| svoya-igra-client | local build (React) |
| svoya-igra-server | local build (Node.js) |
| svoya-igra-mongodb | mongo:7 |
## Порты
| Контейнер | Внутренний | Назначение |
|-----------|-----------|------------|
| server | 3001 | REST API (через NPM) |
## Volumes
| Volume | Контейнер | Путь контейнера | Содержимое |
|--------|-----------|----------------|------------|
| mongodb_data | mongodb | /data/db | MongoDB данные |
| ./server/public | server | /app/public | Статичные файлы |
## Домен
Через NPM (не указан явно).
## Сети
- `services_proxy` (external)
- `internal` (между server и mongodb)
## Env переменные
- `PORT`
- `MONGODB_URI`
- `NODE_ENV`
- `CLIENT_URL`
## Статус
**Не запущен** (не найден в `docker ps`)

View File

@@ -0,0 +1,49 @@
# Nextcloud
## Назначение
Облачное хранилище файлов (self-hosted аналог Google Drive). Синхронизация файлов, фото, документов.
## Контейнеры
| Имя | Образ |
|-----|-------|
| nextcloud_app | nextcloud:latest |
| nextcloud_db | postgres:15-alpine |
| nextcloud_redis | redis:7-alpine |
## Порты
| Контейнер | Внешний | Внутренний | Назначение |
|-----------|---------|-----------|------------|
| nextcloud_db | 5433 | 5432 | PostgreSQL (для прямого доступа) |
| nextcloud_app | — | 80 | Web UI (через NPM) |
## Volumes
| Путь хоста | Контейнер | Путь контейнера | Содержимое |
|-----------|-----------|----------------|------------|
| ./db_data | nextcloud_db | /var/lib/postgresql/data | БД PostgreSQL |
| ./redis_data | nextcloud_redis | /data | Redis данные |
| ./nextcloud_data | nextcloud_app | /var/www/html | Файлы Nextcloud, данные пользователей |
## Домен
`https://cloud.digital-home.site`
## Сети
- `nextcloud_backend` (internal)
- `services_proxy` (external)
## Env переменные
- `POSTGRES_HOST`, `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`
- `NEXTCLOUD_ADMIN_USER`, `NEXTCLOUD_ADMIN_PASSWORD`
- `OVERWRITEPROTOCOL`, `OVERWRITEHOST`
- `NEXTCLOUD_TRUSTED_PROXIES`, `TRUSTED_DOMAINS`
- `REDIS_HOST`
- `PHP_UPLOAD_LIMIT`, `PHP_MEMORY_LIMIT`
## Статус
**Все контейнеры запущены** (Up 4 weeks)
## Заметки
- Файлы Nextcloud монтируются в Jellyfin и Immich для просмотра медиа
- Лимит загрузки файлов: 2048 МБ

View File

@@ -0,0 +1,50 @@
# Immich (photo)
## Назначение
Self-hosted Google Photos альтернатива. Автозагрузка фото с телефона, ML-распознавание лиц и объектов, умный поиск.
## Контейнеры
| Имя | Образ |
|-----|-------|
| immich_server | ghcr.io/immich-app/immich-server:release |
| immich_machine_learning | ghcr.io/immich-app/immich-machine-learning:release |
| immich_redis | redis:7-alpine |
| immich_postgres | tensorchord/pgvecto-rs:pg14-v0.2.0 |
## Порты
| Контейнер | Внутренний | Назначение |
|-----------|-----------|------------|
| immich_server | 2283 | Web UI (через NPM) |
| immich_redis | 6379 | Redis |
| immich_postgres | 5432 | PostgreSQL + pgvecto-rs |
## Volumes
| Путь хоста | Контейнер | Путь контейнера | Содержимое |
|-----------|-----------|----------------|------------|
| ./upload | immich_server | /usr/src/app/upload | Загруженные фото |
| ./model-cache | immich_ml | /cache | ML-модели |
| ./pgdata | immich_postgres | /var/lib/postgresql/data | БД |
| ../nextcloud/nextcloud_data/data | immich_server | /mnt/nextcloud | Файлы Nextcloud (ro) |
| /etc/localtime | immich_server | /etc/localtime | Время (ro) |
## Домен
Через NPM (не указан явно).
## Сети
- `photo_backend` (internal)
- `services_proxy` (external, только immich_server)
## Env переменные
- `DB_HOSTNAME`, `DB_USERNAME`, `DB_PASSWORD`, `DB_DATABASE_NAME`
- `REDIS_HOSTNAME`
- `POSTGRES_PASSWORD`, `POSTGRES_USER`, `POSTGRES_DB`
## Статус
**Все контейнеры запущены** (Up 4 weeks, immich_server healthy)
## Заметки
- Использует `pgvecto-rs` — PostgreSQL с расширением для векторного поиска (нужно для ML)
- immich_machine_learning работает только во внутренней сети

View File

@@ -0,0 +1,38 @@
# Portainer
## Назначение
Web UI для управления Docker. Просмотр контейнеров, образов, volumes, сетей. Визуальный мониторинг всей Docker-инфраструктуры.
## Контейнеры
| Имя | Образ |
|-----|-------|
| portainer | portainer/portainer-ce:latest |
## Порты
| Внутренний | Назначение |
|-----------|------------|
| 8000 | Edge agent |
| 9000 | HTTP Web UI |
| 9443 | HTTPS Web UI |
## Volumes
| Путь хоста | Путь контейнера | Содержимое |
|-----------|----------------|------------|
| /var/run/docker.sock | /var/run/docker.sock | Docker socket |
| ./data | /data | Данные Portainer (пользователи, настройки) |
## Домен
`https://portainer.digital-home.site`
## Сети
- `portainer_backend` (internal)
- `services_proxy` (external)
## Env переменные
Нет (кроме `security_opt: no-new-privileges:true`).
## Статус
**Запущен** (Up 4 weeks)

View File

@@ -0,0 +1,49 @@
# Pulse API (homelab-api)
## Назначение
Backend API для приложения Pulse — трекер привычек, задач, финансов, накоплений. Go REST API + Telegram бот.
## Контейнеры
| Имя | Образ |
|-----|-------|
| homelab-api | local build (Go) |
| homelab-db | postgres:16-alpine |
| pulse-api-dev | local build (dev instance, порт 8081) |
## Порты
| Контейнер | Внешний | Внутренний | Назначение |
|-----------|---------|-----------|------------|
| homelab-api | — | 8080 | REST API (через NPM → api.digital-home.site) |
| pulse-api-dev | 8081 | 8080 | Dev-инстанс API |
| homelab-db | — | 5432 | PostgreSQL |
## Volumes
| Volume | Путь контейнера | Содержимое |
|--------|----------------|------------|
| postgres_data | /var/lib/postgresql/data | БД |
## Домен
`https://api.digital-home.site`
## Сети
- `services_proxy` (external)
- `internal` (между api и db)
## Env переменные
- `DATABASE_URL`
- `JWT_SECRET`
- `PORT`
- `RESEND_API_KEY`
- `FROM_EMAIL`
- `FROM_NAME`
- `APP_URL`
- `TELEGRAM_BOT_TOKEN`
## Статус
**Запущен** (homelab-api: Up 19 hours, homelab-db: Up 4 weeks, pulse-api-dev: Up 4 weeks)
## Подробная документация
→ [[pulse-api]]

View File

@@ -0,0 +1,36 @@
# Pulse Web
## Назначение
Frontend React-приложение для Pulse. Трекер привычек, задач, финансов, накоплений.
## Контейнеры
| Имя | Образ |
|-----|-------|
| pulse-web | local build (React/Vite) |
| pulse-web-dev | local build (dev instance, порт 5174) |
## Порты
| Контейнер | Внешний | Внутренний | Назначение |
|-----------|---------|-----------|------------|
| pulse-web | — | 80 | Prod (через NPM → pulse.digital-home.site) |
| pulse-web-dev | 5174 | 80 | Dev-инстанс |
## Volumes
Нет persistent volumes.
## Домен
`https://pulse.digital-home.site`
## Сети
- `services_proxy` (external)
## Env переменные
- `VITE_API_URL`
## Статус
**Запущен** (pulse-web: Up 12 days, pulse-web-dev: Up 4 weeks)
## Подробная документация
→ [[pulse-web]]

View File

@@ -0,0 +1,46 @@
# Review Bot
## Назначение
AI-бот для автоматического code review Pull Request'ов в Gitea. Получает вебхуки от Gitea, клонирует репозиторий, анализирует изменения через Anthropic Claude и оставляет комментарии.
## Контейнеры
| Имя | Образ |
|-----|-------|
| review-bot | local build (Node.js) |
## Порты
| Внешний | Внутренний | Назначение |
|---------|-----------|------------|
| 3300 | 3300 | HTTP webhook endpoint |
## Volumes
| Volume | Путь контейнера | Содержимое |
|--------|----------------|------------|
| review-bot-logs | /var/log/review-bot | Логи ревью |
## Домен
Нет (доступен только изнутри сети).
## Сети
- `services_proxy` (external)
## Env переменные
- `GITEA_URL`
- `GITEA_TOKEN`
- `WEBHOOK_SECRET`
- `ANTHROPIC_URL` (прокси через AI-proxy на 192.168.31.103:3301)
- `PROXY_KEY`
- `LOG_FILE`
- `CLONE_BASE_DIR`
- `PORT`
## Статус
**Запущен** (Up 6 days)
## Заметки
- Использует AI-proxy (`192.168.31.103:3301`) т.к. Anthropic API key работает только с основной машины OpenClaw
- Вебхук настроен для репозиториев pulse-api и pulse-web
- Директория для клонирования: `/tmp/review-bot-clones`

View File

@@ -0,0 +1,52 @@
# Savings (семейные накопления)
## Назначение
Приложение для совместного управления накоплениями. Go backend + React frontend. Поддержка категорий накоплений, участников, регулярных планов, начисления процентов.
## Контейнеры
| Имя | Образ |
|-----|-------|
| savings-backend | local build (Go) |
| savings-frontend | local build (React) |
## Порты
| Контейнер | Внутренний | Назначение |
|-----------|-----------|------------|
| savings-backend | 9090 | REST API (через NPM) |
| savings-frontend | — | Web UI (через NPM) |
## Volumes
| Путь хоста | Контейнер | Путь контейнера | Содержимое |
|-----------|-----------|----------------|------------|
| ./savings.db | backend | /root/savings.db | SQLite БД |
## Домен
Через NPM (не указан явно).
## Сети
- `services_proxy` (external)
## Env переменные
**Backend:**
- `DB_NAME`, `DB_TYPE`
- `JWT_SECRET`, `JWT_EXPIRES_IN`
- `PORT`, `GIN_MODE`
- `FRONTEND_URL`
- `INTEREST_CALCULATION_ENABLED`, `INTEREST_CALCULATION_INTERVAL`
- `SMTP_HOST`, `SMTP_PORT`, `SMTP_USERNAME`, `SMTP_PASSWORD`
- `FROM_EMAIL`, `FROM_NAME`, `EMAIL_ENABLED`
**Frontend (build args):**
- `REACT_APP_API_URL`
- `REACT_APP_APP_NAME`
- `REACT_APP_VERSION`
## Статус
**Не запущен** (не найден в `docker ps`)
## Заметки
- Использует SQLite (не PostgreSQL) — данные в одном файле `savings.db`
- Встроенный расчёт процентов по расписанию

View File

@@ -0,0 +1,41 @@
# Nginx Proxy Manager (services)
## Назначение
Обратный прокси-сервер. Управляет входящим трафиком (HTTP/HTTPS), SSL-сертификатами (Let's Encrypt), маршрутизирует запросы к контейнерам по доменам `*.digital-home.site`.
## Контейнеры
| Имя | Образ |
|-----|-------|
| nginx_proxy_manager | jc21/nginx-proxy-manager:latest |
## Порты
| Внешний | Внутренний | Назначение |
|---------|-----------|------------|
| 80 | 80 | HTTP |
| 81 | 81 | Web UI (управление NPM) |
| 443 | 443 | HTTPS |
## Volumes
| Volume | Путь | Содержимое |
|--------|------|------------|
| ./data | /data | Конфиги прокси-хостов, БД |
| ./letsencrypt | /etc/letsencrypt | SSL-сертификаты Let's Encrypt |
## Домен
Нет (сам является точкой входа). UI доступен напрямую через порт 81.
## Сети
- `services_proxy` (создаётся здесь как `proxy`, используется всеми другими сервисами)
## Env переменные
Нет конфигурационных env-переменных.
## Статус
**Запущен** (Up 26 hours)
## Заметки
- Это корневой сервис инфраструктуры — все остальные подключаются к сети `services_proxy`
- Управление через UI на порту 81 (только из локальной сети)

View File

@@ -0,0 +1,31 @@
# Storybook
## Назначение
Storybook для разработки UI-компонентов pulse-web. Изолированная среда для разработки и документирования React-компонентов.
## Контейнеры
| Имя | Образ |
|-----|-------|
| storybook | local build |
## Порты
| Внешний | Внутренний | Назначение |
|---------|-----------|------------|
| 6006 | 80 | Storybook UI |
## Volumes
Нет.
## Домен
Нет (доступен напрямую по порту 6006).
## Сети
- `services_proxy` (external)
## Env переменные
Нет.
## Статус
**Запущен** (Up 4 weeks)

View File

@@ -0,0 +1,35 @@
# Uptime Kuma
## Назначение
Мониторинг доступности сервисов. Следит за uptime всех хостов и URL, отправляет уведомления при падении.
## Контейнеры
| Имя | Образ |
|-----|-------|
| uptime-kuma | louislam/uptime-kuma:1 |
## Порты
| Внутренний | Назначение |
|-----------|------------|
| 3001 | Web UI (через NPM) |
## Volumes
| Путь хоста | Путь контейнера | Содержимое |
|-----------|----------------|------------|
| ./data | /app/data | БД мониторинга (SQLite), конфиги |
## Домен
Через NPM (не указан явно).
## Сети
- `uptime_backend` (internal)
- `services_proxy` (external)
## Env переменные
Нет.
## Статус
**Запущен** (Up 5 days, healthy)

View File

@@ -0,0 +1,38 @@
# Vaultwarden (vault)
## Назначение
Self-hosted менеджер паролей, совместимый с клиентами Bitwarden. Хранит пароли, заметки, карты в зашифрованном виде.
## Контейнеры
| Имя | Образ |
|-----|-------|
| vaultwarden | vaultwarden/server:latest |
## Порты
| Внутренний | Назначение |
|-----------|------------|
| 80 | Web UI (через NPM) |
## Volumes
| Путь хоста | Путь контейнера | Содержимое |
|-----------|----------------|------------|
| ./data | /data | Зашифрованная БД паролей |
## Домен
`https://vault.digital-home.site`
## Сети
- `vault_backend` (internal)
- `services_proxy` (external)
## Env переменные
- `DOMAIN`
- `LOG_LEVEL`
- `EXTENDED_LOGGING`
- (закомментированы: `SIGNUPS_ALLOWED`, `ADMIN_TOKEN`, SMTP-настройки)
## Статус
**Запущен** (Up 4 weeks, healthy)

View File

@@ -0,0 +1,48 @@
# Vikunja
## Назначение
Self-hosted менеджер задач (аналог Todoist/Trello). Используется для личных задач, проектов, канбан-досок.
## Контейнеры
| Имя | Образ |
|-----|-------|
| vikunja | vikunja/vikunja:latest |
| vikunja_db | postgres:15-alpine |
## Порты
| Контейнер | Внутренний | Назначение |
|-----------|-----------|------------|
| vikunja | 3456 | Web UI (через NPM) |
| vikunja_db | 5432 | PostgreSQL |
## Volumes
| Путь хоста | Контейнер | Путь контейнера | Содержимое |
|-----------|-----------|----------------|------------|
| ./db | vikunja_db | /var/lib/postgresql/data | БД задач |
| ./files | vikunja | /app/vikunja/files | Вложения к задачам |
## Домен
`https://tasks.digital-home.site`
## Сети
- `vikunja_backend` (internal)
- `services_proxy` (external)
## Env переменные
- `VIKUNJA_DATABASE_TYPE`, `VIKUNJA_DATABASE_HOST`, `VIKUNJA_DATABASE_DATABASE`
- `VIKUNJA_DATABASE_USER`, `VIKUNJA_DATABASE_PASSWORD`
- `VIKUNJA_SERVICE_PUBLICURL`
- `VIKUNJA_SERVICE_JWTSECRET`
- `VIKUNJA_SERVICE_ENABLEREGISTRATION`
- `VIKUNJA_SERVICE_ENABLETASKATTACHMENTS`
- `VIKUNJA_SERVICE_TIMEZONE`
## Статус
**Запущен** (Up 4 weeks)
## Заметки
- API токен для автоматизации: `tk_03787e3778789fd5bfaff0542a8dd9390aae0f82`
- Проекты: Inbox(1), Личное(3), Dev(4), Япония(5), Финансы(6)

View File

@@ -0,0 +1,37 @@
# VPN Invite
## Назначение
Сервис для управления приглашениями в VPN. Node.js приложение с SQLite.
## Контейнеры
| Имя | Образ |
|-----|-------|
| vpn-invite-vpn-invite-1 | node:20-alpine |
## Порты
| Внутренний | Назначение |
|-----------|------------|
| 3500 | HTTP API (через NPM) |
## Volumes
| Volume | Путь контейнера | Содержимое |
|--------|----------------|------------|
| vpn-invite-data | /data | SQLite БД инвайтов |
| ./ | /app | Код приложения |
## Домен
Через NPM (не указан явно).
## Сети
- `services_proxy` (external)
## Env переменные
- `ADMIN_KEY`
- `PORT`
- `DB_PATH`
## Статус
**Запущен** (Up 21 hours)

View File

@@ -0,0 +1,35 @@
# VPN Router (sing-box)
## Назначение
VPN-маршрутизатор на базе sing-box. Управляет VPN-трафиком, поддерживает разные протоколы.
## Контейнеры
| Имя | Образ |
|-----|-------|
| vpn-router | ghcr.io/sagernet/sing-box:v1.10.7 |
## Порты
`network_mode: host` — использует все порты хоста напрямую.
## Volumes
| Путь хоста | Путь контейнера | Содержимое |
|-----------|----------------|------------|
| ./config | /etc/sing-box | Конфиг sing-box (config.json) |
## Домен
Нет (работает на уровне сети).
## Сети
`network_mode: host` (нет Docker-сетей).
## Env переменные
Нет.
## Статус
**Не запущен** (не найден в `docker ps`)
## Заметки
- `cap_add: NET_ADMIN` — нужно для управления сетевыми интерфейсами
- Конфиг в `./config/config.json`

View File

@@ -0,0 +1,40 @@
# Webhook Deploy
## Назначение
Python-сервер для автоматического деплоя через вебхуки. Получает HTTP-запрос → запускает Docker Compose команды для обновления сервисов.
## Контейнеры
| Имя | Образ |
|-----|-------|
| deploy-webhook | python:3.12-alpine |
## Порты
| Внешний | Внутренний | Назначение |
|---------|-----------|------------|
| 9000 | 9000 | HTTP webhook endpoint |
## Volumes
| Путь хоста | Путь контейнера | Содержимое |
|-----------|----------------|------------|
| ./server.py | /app/server.py | Python код сервера |
| /var/run/docker.sock | /var/run/docker.sock | Docker socket |
| /opt/digital-home | /opt/digital-home | Все проекты (для деплоя) |
| /usr/bin/docker | /usr/bin/docker | Docker CLI бинарник |
## Домен
Нет (внутренний доступ).
## Сети
- `services_proxy` (external)
## Env переменные
Нет (конфиг в `server.py`).
## Статус
**Статус неизвестен** (не найден в `docker ps`)
## Заметки
- Имеет доступ к Docker socket и всем проектам — может деплоить любой сервис

View File

@@ -0,0 +1,58 @@
# 🏠 Планирование домашней инфраструктуры
## Текущий сетап
- **Mini-PC** — Proxmox, VM с Docker-сервисами + OpenClaw
- **Роутер** — Xiaomi Router AX3200
- **Умный дом** — Aqara M100 хаб, Zigbee устройства, колонки Яндекс
## Схема сети (план)
```
Роутер (коридор/гостиная)
└── Cat6 → Кабинет
Свитч
├── Mini-PC (Proxmox)
├── NAS (Synology DS223j)
├── Мой комп
└── Комп Светы
UPS в кабинете питает: свитч + mini-PC + NAS
```
## 🛒 Список покупок
### 1. NAS + Диски (~46к₽)
- **Synology DS223j** — ~28-30к₽
- [Ситилинк](https://www.citilink.ru/product/setevoe-hranilische-nas-synology-ds223j-2-bay-nastolnyi-rtd1619b-2049554/)
- 2 отсека, RAID 1, Synology DSM
- Чисто хранилище: бэкапы, файлы, медиа
- **2× WD Red Plus 6TB (WD60EFPX)** — ~8-9к₽ за штуку
- [Ситилинк](https://www.citilink.ru/product/zhestkii-disk-wd-red-plus-wd60efpx-6tb-hdd-sata-iii-3-5-1970104/)
- CMR, 5400 RPM, 256 МБ кеш, 24/7
- RAID 1 = 6 ТБ полезного пространства
### 2. UPS / ИБП (~8-12к₽)
- **APC Back-UPS 650-1000VA**
- Защита от отключений электричества
- Питает: mini-PC + NAS + свитч
- 15-20 минут на корректное завершение
### 3. Свитч (~3к₽)
- **TP-Link TL-SG108E** (8 портов, управляемый)
- Гигабит, VLAN поддержка
- Ставится в кабинет
### Итого: ~57-65к₽
## 📝 Заметки
- NAS используется только как хранилище (SMB/NFS), Docker остаётся на VM
- При переезде — один Cat6 кабель от роутера до кабинета
- Wi-Fi с AX3200 покрывает телефоны, колонки, умный дом
- Home Assistant на Proxmox свяжет Aqara + Яндекс
## Очерёдность
1. NAS + диски — расширение хранилища
2. UPS — защита данных
3. Свитч — когда устройств станет >3 в кабинете

View File

@@ -0,0 +1,24 @@
## Распределение сетевой нагрузки
- Перенести Tailscale с машины OpenClaw в отдельную ВМ для постоянного доступа к домашней сети (минимальный образ, будет только Tailscale)
- Создать ВМ для sing-box, который всегда будет подключен к серверу Риги
- Удалить с OpenClaw VM sing-box, переправлять трафик через SingBox VM
## Проверить после прибытия с отпуска
- Tailscale на Services VM (--accept-routes нужно выключить, так как из-за этого не удается выйти в доступ через SSH)
-
## Улучшения
- Поставить NAS хранилище
- Подумать о переносе каких-то сервисов в отдельную машину, чтобы распределить нагрузку
- Установить ИБП
- Создать уведомления в ТГ о доступности ВМ с ВПН-ами и сервисов, потому что может отключиться ВПН и нужно будет его включить
- Создать правило перезапуска sing-box при сетевой ошибке или моргании сети
- Создать правило перезапуска OpenClaw gateway после ошибки sing-box
## Проекты
- Отключить вкладку и правило добавления доходов/затрат
-

View File

@@ -1,11 +0,0 @@
Получить статистику по дням
```bash
npx ccusage@latest
```
Получить статистику в режиме реального времени
```bash
npx ccusage@latest blocks --live
```
Новый текст, чтобы оценить синхронизацию - ИЗМЕНИЛ

View File

@@ -1,20 +0,0 @@
Найти процессы по порту
```bash
netstat -ano | findstr :9090 | findstr LISTENING
```
Убить процесс
```bash
taskkill /PID 8768 /F
powershell.exe -Command "Stop-Process -Id 8768 -Force"
```
Запустить npx приложение на порту
```bash
cd D:/Pet_projects/savings/react-app/savings-mobile && npx serve dist -p 3000
```
```
46U8w7EdHd6CBdrd3TyA
```

View File

@@ -0,0 +1,9 @@
```
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```
```
OPENROUTER
```
d4f4f27c-aa88-4f81-b24a-07da456b6c08:5a63fff139d294e29dfe0cabe970526a
```
FAL

10
Личное/Игры.md Normal file
View File

@@ -0,0 +1,10 @@
https://s1.byrutorg.com/horizon-forbidden-west-complete-edition
https://s1.byrutorg.com/horizon-zero-dawn-remastered
https://s1.byrutorg.com/the-last-of-us-part-2
https://s1.byrutorg.com/1-dying-light-2-stay-human
https://s1.byrutorg.com/call-of-duty-black-ops-6
https://s1.byrutorg.com/split-fiction
https://s1.byrutorg.com/call-of-duty-ghosts-deluxe-edition
https://s1.byrutorg.com/download/torrent/call_of_duty_modern_warfare/1-1-0-358
https://s1.byrutorg.com/call-of-duty-black-ops-cold-war

View File

@@ -0,0 +1,12 @@
Пользователи:
- Даня +
- Света +
- Юлиана +
- Виталя +
- Коля +
- Паша (Виталя) +
- Юля Ш.
- Юля М.
- Даша
- Ксюша +

View File

@@ -0,0 +1,42 @@
Основной объект
Дата старта
Дата завершения
Период - Q1, Q2, ..., Year
Родитель - Year
Деталь
Команда
План (в млн)
Основной объект
--------
Q1 2026
01.01.2026
31.03.2026
Q1 2026
2026
Деталь
DFS | 20 | Q1 2026 | 50
DTI | 30 | Q1 2026
KPI | 20 | Q1 2026
-----
Q2 2026
01.01.2026
31.03.2026
Q1 2026
2026
Деталь
DFS | 20 | Q2 2026
DTI | 30 | Q2 2026
2026
DFS | 20+ 30 + 40 + 50 |

View File

@@ -1,16 +1,20 @@
1. Проставить значение настройки "NrbErpHeadProject" 1. Проставить значение настройки "NrbErpHeadProject"
2. Проставить значение настройки "NrbAsyncServiceUri" 2. Проставить значение настройки "NrbAsyncServiceUri" `https://async.prod.plt.adsw.io/`
3. Проставить значение настройки "NrbPresaleProjectServiceKey" 3. Проставить значение настройки "NrbPresaleProjectServiceKey"
4. Проставить значение настройки "NrbIsERPIntegrationEnabled" 4. Проставить значение настройки "NrbIsERPIntegrationEnabled"
5. Проставить значение настройки "ServiceAccountName" 5. Проставить значение настройки "NrbOpenProjectUrl"
6. Проставить значение настройки "ServiceAccountSecret" 6. Проставить значение настройки "NrbErpServiceSecret"
7. Проверить настройку "GatewayURLKey" 7. Проверить настройку "GatewayURLKey"
Секреты Секреты CRM
1. Dev CRM `20b6702d-a3f7-4dfa-baad-640da98b727c` 1. Dev CRM `20b6702d-a3f7-4dfa-baad-640da98b727c`
2. Preprod CRM `347bf64d-8920-4de6-a0f1-654c2ab15fda` 2. Preprod CRM `347bf64d-8920-4de6-a0f1-654c2ab15fda`
3. Prod CRM `24b9aef3-dffb-4f9e-9c5d-fa8a9802276f` 3. Prod CRM `24b9aef3-dffb-4f9e-9c5d-fa8a9802276f`
Cекреты ERP
1. Dev `067d72e8-2728-493b-b7b0-4fa4c482d921`
2. Prod `ff915955-844e-4a93-a933-c43cfc84adf4`
Dev Private Gateway - `https://private-api-gateway-feature-itdev-1381.dev.plt.adsw.io/query` Dev Private Gateway - `https://private-api-gateway-feature-itdev-1381.dev.plt.adsw.io/query`
Dev Async - `https://async-feature-itdev-1381.dev.plt.adsw.io/` Dev Async - `https://async-feature-itdev-1381.dev.plt.adsw.io/`