Разработку пет-проекта с прицелом на open source в моем случае можно описать выражением: корабль любви разбился о айсберг бытовухи.

Но давайте для начала разберемся, кто я и о чем идет речь.

У меня нет профильного технического образования. За плечами учеба на экономиста, курсы по JS на фронт и пара лет работы на беке.
Поэтому мои выводы могут показаться банальными или очевидными - прошу простить эту вольность. К моему стыду, я плохо учусь на чужих ошибках, поэтому приходится стабильно совершать свои.


Почему вообще этот проект

Соответственно моему бэкграунду и интересам я и выбрал проект на стыке этих тем - приложение для ведения и учета криптопортфеля.

К тому же эта идея уже много лет крутилась у меня в голове, так что в какой-то момент было решено: либо сейчас, либо никогда.

Тут может возникнуть вопрос: чем тебя не устроили Excel и онлайн-сервисы?

С Excel у меня отдельная история. Я, пожалуй, из редких экономистов, которых от него уже тошнит. Да, это почти совершенный инструмент и очень удобный, если уметь им пользоваться, но для этой задачи я его практически не использовал - максимум для отдельных расчетов.

С онлайн-сервисами тоже не все слава богу:

  • во многом ограничены

  • не дают нужной гибкости

  • работают только с логикой «купил - продал»

А в крипте нюансов сильно больше.

Плюс хотелось:

  • расширить аналитику

  • настроить уведомления

  • нормально собирать данные

Ну и отдельно - риски:

  • сервис могут забанить

  • могут заблокировать страну

  • данные могут пропасть

  • сам сервис может закрыться

Перенос данных - отдельный ад. Я переносил портфель с cryptocompare на dropstab, и это заняло у меня несколько дней, буквально с 9 до 5, в режиме копировать-вставить. Такой экспириенс и врагу не пожелаешь.


MVP

Для начала я поставил перед собой цель - просто выпустить MVP.
С базовым функционалом и минимальным набором, пригодным для работы.

Сначала, конечно, была мысль сделать веб-сервис, но быстро стало понятно, что бюджетом в «пачку сухариков» тут не обойдешься.

Начал искать, можно ли сделать десктопное приложение, если ты знаешь только JS.
Так я наткнулся на Electron и Tauri.

Решил:

  • Electron - для MVP

  • Tauri - для полной версии (потом передумал после тестов)

И на этом этапе концепция оформилась окончательно:

десктопное приложение с локальной БД для учета криптопортфеля


Первые звоночки

После этого возник новый вопрос:
а что делать с мобильными устройствами?

Как связать десктоп и телефон и можно ли это сделать малой кровью?

Я, как обычно, пошел гуглить и придумал решение, которое до сих пор не протестировал и не уверен, что оно вообще работает:

  • десктоп хостит фронт

  • доступ через туннель

  • логика остается на ПК

Плюс придумал режим «только просмотр», чтобы можно было пантоваться перед корешами или просить советы.

Но это уже явно было не для MVP.


MVP я все-таки сделал

Справедливости ради - MVP я закончил.

Заняло это у меня примерно 2.5 месяца. Для кого-то это долго, но для первой попытки я считаю результат вполне нормальным.

И вроде бы всё хорошо… но нет.


Первая ошибка - документация

Я не писал нормальную документацию.

Точнее, как - что-то писал:

  • блокнот

  • стикеры

  • заметки

Но структуры не было.

Как это выглядело
Kanban MVP
Kanban MVP

И проблема проявилась сразу после завершения MVP - когда я сел подводить итоги.

Я понял, что:

я уже плохо помню, почему принимал часть решений

И пришлось тратить кучу времени на восстановление логики проекта двухмесячной давности.


Аппетит приходит во время еды

Дальше всё пошло по классике.

Я начал находить всё новые API и идеи:

  • Dexscreener

  • Cryptopanic

  • Obsidian

Плюс родилась идея подключить TON-экосистему:

  • proxy

  • vpn

  • storage

  • connect

И всё это уже начинало напоминать известную сцену из «Собачьего сердца».


Полная версия

Дальше я решил сделать полноценную версию - «то же самое, но больше».

Начал с документации, написал манифест.

Манифест
Цель:
1. Все тоже что и в MVP но максимально развернуто удобно и функционально.
	Имеется ввиду: 
	 - Транзакции
		 - Движение средств
		 - Источник
		 - Комиссии
		 - Свопы с монеты на монету
		 - Стейкинг
			 - Стейкинг с кастомной наградой(монета стейка или другая)
			 - Нужна страница  со сводной инфой
		 - Купля/Продажа
		 - Дропы
			 - Разделить дропы на кастомные виды
		- Место хранения меток
		- Логирование [[FIFO]] (плагин) и расчеты на этой основе
	- Графики
		- Кастомные графики
		- График нет ворса как в MVP
	- Метрики
		- Сводная по аккаунту
		- Сводная по портфель
		- Сводная по ассету
		- и другие по ходу дела
	- Рыночные данные
		- Брать рыночные данные по ассетам пользователя с апи
2. Новое:
	- Текстовые данные в Markdown для взаимной интеграции с Obsidian
		- Заметки к операциям и портфолио
		- Заметки к графикам, а значит графики нужно хранить
		- Комментарии
		- Планы на ассеты
		- Страница со всеми заметками
	- Календарь
		- С отметками транзакций и заметок
	- Мелочи для удобства
		- Калькулятор и кастомные формулы
			- Калькулятор по стейкингу
			- Калькулятор по цене на основе капы
		- Форма для массовых добавлений транзакций
	- Фронт
		- Сделать и настроить работу в нескольких вкладках внутри приложения (имитация окон браузера)
	- Операции и стратегии записывать в заметки
		- Ребалансировка
		- Лесничная продажа и покупка
		- Вставка реал тайм данных по выбору
		- Шаблоны для этого
	- Исторические данные в DuckDB
		- Опциональное хранение
		- Кастомная глубина и период
3. Изменения:
	- Рыночные данные:
		- Брать рыночные данные из CCXT и апишек сервисов
	- Редизайн (смесь экселя и Obsidian)
	- Импорт/Экспорт оставить по старому и добавить новые таблицы и бд

Подход:
1. Сделать упор в разработке на бэкенд, учитывать разные UI клиенты
	- UI клиенты
		- Мини апка в тг
		- Браузер с пк или телефона
		- Учесть возможность поднять сервис бэка на Raspberry PI, с клиентами на локалке или тунель
2. Фронт занимается только отображением, минимум логики
3. Монорепа гита на 3 компонента с одной нодой
4. Хранение данных
	- SQLite
		- Таблицы
			- [[User]]
			- [[Transactions]]
			- [[Staking]]
			- [[Marks]] Место хранения
				- Mermaid можно отобразить последовательность трансферов
			- [[Swaps]]
			- [[Asset]]
			- [[Portfolio]]
			- [[Library]] - названия монет
			- [[Market]] - Рыночные данные
			- [[Drops]]
			- [[Notes]] - метаданные по запискам
	- DuckDB
		- Хранить данные для отрисовки графиков
		- Хранить аналитику и метрики
		- ~~Использовать GraphQL для работы~~
		- Использовать для статических данных
	- Заметки
		- Создаются на бэке и хранятся в .md файлах
	- Local Storage
		- Настройки пользователя
			- Тема
			- Язык
5. Обработка данных
	- Данные для метрик и графиков обрабатываются на бэке
	- CCXT периодично берет данные по цене из бирж
	- Периодически стучатся к CoinGecko за сводными рыночными данными

Стек:
1. Бэк
	- Хранение данных
		- SQLite - общие данные
		- DuckDB - данные для графиков и метрик
		- MD - заметки
	- Redis - менеджерить очередь и кэш 
		- использовать для часто запрашиваемых данных, кэширование, отложенных или регулярных задач 
		- проконтролить использование памяти и сохранность при перезапуске
	- Nest.js - фреймворк
	- Prisma - для работы с SQLite
	- Kysely - для работы с DuckDB
	- ~~GraphQL~~ + WebSocket - для получения автообновляемых данных и для данных в заметки
	- CCXT - для сбора данных с бирж
	- CoinGecko Defilama - для общих рыночных данных
2. Фронт
	- Vue3 - фреймворк
	- Pinia - стор
		- Использовать root store
	- Vue-router - роуты для переходов
	- Графики - вручную или VueChar
	- Заметки 
		- md-editor-v3 + highlight.js
		- tui-editor / @toast-ui/vue-editor - для WYSIWYG
		- LaTeX + Math.js для отображения формул и калькуляций
		- Mermaid для диаграмм
3. Электрон как обертка для десктопа
4. Мониторинг
	- Вынести мониторинг и логирование в отдельный плагин
	- Логирование - логировать все действие в консоль бека
	- Вывести логи в спец владку на фронте
	- Мониторить использование ресурсов и фоновые задачи
	- Redis - чекать регулярные задачи и кэш данные, демонстрировать юзеру 
		- redis-cli/redis-stat или Prometheus + Grafana
5. Общее
	- TypeScript
	- Минимизирую сторонние библиотеки
	- Модульность

Плагины
1. GraphQL для кастомных запросов и графиков
2. Мониторинг и логирование

Первым делом решил убрать узкое место MVP.

В MVP я использовал CoinGecko, и обновление данных занимало около 15 минут из-за лимитов API. Для подобного приложения это, по сути, приговор.

В полной версии я:

  • отказался от лишнего хранения и обновления данных

  • добавил CCXT

  • начал учитывать лимиты API (о которых раньше вообще не думал)

Вывод тут простой:

прежде чем что-то строить, стоит понять ограничения источников данных


База и логика

Дальше я начал собирать схемы в Prisma и продумывать аналитический модуль.

И тут до меня дошло, почему почти везде только логика «купил - продал».

Потому что всё остальное:

  • сложно описать

  • сложно хранить

  • еще сложнее анализировать

И тут важный момент:

если вы хотите «сделать лучше», сначала разберитесь, почему уже сделано именно так


Git и инфраструктура

Отдельной болью стали git и node.

До этого мой опыт был на уровне:

  • npm install

  • push

  • pull

  • иногда cherry-pick

А тут нужно было настраивать нормальный workflow.


MVP

Я не заморачивался:

  • одна репа

  • отдельные node_modules под фронт, бэк и Electron

Работало нормально, пока не дошло до сборки.

Проблемы:

  • упаковка БД

  • копирование

  • дубли зависимостей

В итоге в сборке было два node_modules, и приложение раздувалось примерно на +300 МБ сверху.

Решение:

просто перенес Electron в бэк

Не лучшее, но рабочее.


Полная версия

Во второй версии я решил сделать монорепу.

Сначала казалось, что это решит все проблемы.

На практике:

  • сложная структура

  • куча нюансов с зависимостями

  • легко потеряться

Возможно, дело в опыте. Но на тот момент это выглядело как лишняя сложность.

До этапа сборки я, кстати, так и не дошел.


Где всё остановилось

Я не то чтобы специально бросил проект или выгорел - просто в какой-то момент так сложились обстоятельства, что я перестал им заниматься.

Прошло несколько месяцев.

Когда я вернулся, свежим взглядом стало видно:

я слишком много заложил в первую версию

Причем настолько, что довести её до конца в таком виде было бы крайне сложно.


Итог

В итоге я пришел к довольно очевидному выводу:

лучше сделать твердый минимум, чем пытаться собрать жидкий максимум

И, как ни странно, снова пришел к формуле:
«купил - продал»


Где я ошибся

  • Документация Если её нет - вы очень быстро теряете контекст. Буквально через пару месяцев вы будете разбираться в своем же проекте как в чужом, вспоминая, «что вообще здесь происходит и зачем я это делал».

  • Понимание рынка Если в существующих решениях нет «очевидной» для вас фичи - почти наверняка это не случайность. Скорее всего, вы просто пока не видите всей сложности, которая за этим стоит.

  • Оценка своих сил Желание сделать «сразу нормально» почти всегда заканчивается тем, что вы не делаете вообще ничего законченного. Лучше маленький, но завершенный кусок, чем бесконечная стройка.

  • MVP MVP - это не заготовка продукта и не «первая версия сервиса». Это способ максимально быстро столкнуться с реальными проблемами и понять, где вы ошиблись в планировании.

  • Реалити-чек Если в какой-то момент вы перестаете вывозить - это не всегда вопрос дисциплины. Иногда это сигнал, что вы переоценили масштаб и нужно не «дожимать», а переосмыслить подход.


Если честно, я писал всё это в первую очередь для себя - чтобы хоть как-то разложить по полочкам, что вообще произошло и где именно я свернул не туда.

Но если вы сейчас читаете это и ловите себя на мысли, что у вас происходит примерно то же самое - возможно, это повод остановиться и чуть пересобрать подход, пока проект окончательно не ушёл в разнос.

Комментарии (0)