7-Solutions — пополнение склада
Python-прототип, который по ZIP-архивам с Excel от IEK и Systeme Electric считает объяснимые рекомендации по заказам.
О проекте
Команда: 7-Solutions
Кейс HackAlem.ai: Логистика — Электрокомплект · ekt.kz
Стадия: Рабочий MVP
Задача кейса: Автоматический расчёт заказов поставщикам для пополнения склада, с утверждением менеджером
Суть
Python-прототип, который по ZIP-архивам с Excel от IEK и Systeme Electric считает объяснимые рекомендации по заказам. Менеджер уточняет остаток и количество, утверждает заказ и выгружает CSV. Есть стресс-сценарии дефицита и сверка месячных продаж с динамикой.
Как устроено
importer.py читает ZIP с Excel в памяти через openpyxl и сверяет месячные продажи с динамикой накладных. Выбросы определяются по медиане и MAD накладных с порогом max(5×медиана, медиана+6×1.4826×MAD), повторные крупные покупки одного клиента сохраняются. Сезонность смешивает товарную (65%) и поставщика (35%). Базовый спрос считается по 6 последним полным месяцам. Если известны дни отсутствия товара, спрос восстанавливается. Рост считается по медиане год к году или берётся «Кэф. Роста». Заказ округляется с учётом минимума и кратности, позиции в бухтах и метрах блокируются до согласования единиц. Утверждение ручное. Хранение в SQLite локально или PostgreSQL на Vercel, есть сценарии стресса запасов.
Ключевые решения
- median/MAD outlier detection
- seasonality blending
- stockout demand reconstruction
- YoY growth
- MOQ/multiplicity
- stress-test scenarios
- data reconciliation
Особенности
Подробно разобраны особенности исходных данных: MOQ у IEK означает минимум, у Systeme кратность; единицы в бухтах и метрах требуют согласования; stockout-периоды не выдумываются. Есть диагностическая сверка месячной формы с накладными и сценарии «Сильный стресс» с датой дефицита.
Стек
Python · WSGI · openpyxl · SQLite · PostgreSQL · Supabase · Vercel · JavaScript · HTML/CSS
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-2d79bdb0-7-solutions.
README
README.md7-Solutions — пополнение склада
Рабочий прототип для кейса «Автоматический расчёт заказов поставщикам для пополнения склада», ТОО «Электрокомплект». HackAlem AI, 23 сентября 2026. Команда: Мадияр и Асанали.
Приложение читает предоставленные ZIP с Excel, формирует объяснимые рекомендации для IEK и Systeme Electric, позволяет уточнить остаток и количество, утверждает заказ и выгружает CSV для Excel. Данные обрабатываются локально; внешние AI API не вызываются. Прогноз — воспроизводимая статистическая модель. Codex использован при разработке.
Текущее состояние передачи
Размещение на Vercel подготовлено в asanali/vercel-deploy от main 470b1a0, без изменений отменённой ветки Render. Python WSGI и существующий интерфейс сохранены. Постоянные аккаунты, набор данных и заказы хранятся в PostgreSQL; SQLite на Vercel не используется. Инструкция и фактический статус публикации — VERCEL.md.
После PR #2 подготовлена отдельная ветка madiyar/cloud-deploy: PostgreSQL, WSGI/Gunicorn, закрытая облачная регистрация, перенос с резервной копией и конфигурация Render. Сайт пока не размещён, реальные данные в Neon не перенесены: доступ Render к приватному репозиторию ждёт администратора BAITC-Hacks; Мадияр попросил пока передать проект Асанали. Инструкция, проверки и ограничения — DEPLOYMENT.md. Локальный запуск ниже остаётся рабочим. Промпт продолжения — PROMPT_ASANALI.md.
Проверить за 90 секунд
После запуска создать локальный аккаунт (вкладка «Создать аккаунт») и нажать Демо-сценарии → План Б. Выбран DEMO-001. Нажать «По плану», затем «Сильный стресс»: график и таблица покажут дату дефицита, непокрытый спрос и дополнительную срочную партию. Открыть расчёт товара: история, всплеск, формула заказа и ручное подтверждение доступны в одной карточке. Полный сценарий защиты — DEMO.md.
Интерфейс оформлен в стиле Dynamic Glass / Apple Liquid Glass: полупрозрачные материалы, мягкий фон, системная типографика, адаптация к узкому экрану и reduced motion. Стек шрифтов: -apple-system, BlinkMacSystemFont, локальный SF Pro Text/Display, Segoe UI Variable, Segoe UI, system-ui. San Francisco используется только там, где доступен; файлы шрифтов Apple не распространяются, внешних запросов шрифтов нет.
Запуск
Требуется Python 3.11 или новее и openpyxl 3.1.x.
python -m venv .venv
# Windows:
.venv\Scripts\activate
# macOS / Linux: source .venv/bin/activate
python -m pip install -r requirements.txt
python server.py
Открыть http://127.0.0.1:8765. На исходном компьютере можно запустить run.cmd: он использует готовый Python из среды Codex, если тот доступен. Альтернативный порт: python server.py --port 8766.
Код работает без сети после установки зависимости. Сервер слушает только localhost. Это локальный прототип, с локальными аккаунтами, не облачный production-сервис; не следует открывать его напрямую в интернет.
Данные
В интерфейсе загрузить оба архива Systeme electric.zip и IEK.zip. Они читаются в памяти, без извлечения путей ZIP на диск. Лимит загрузки — 40 МБ; суммарного распакованного размера Excel — 150 МБ. Импорт ZIP обновляет соответствующего поставщика. JSON заменяет весь набор.
Также доступен импорт из командной строки:
python importer.py "Systeme electric.zip" "IEK.zip"
CLI-результат хранится в data/dataset.json. При первом чтении сервер переносит этот набор в SQLite. После появления базы импортировать новые ZIP/JSON через интерфейс; простое изменение старого JSON не заменяет актуальную базу. В локальной сборке для команды данные уже загружены. Исходный архив для передачи кода и Git исключают коммерческие данные, базу аккаунтов, сессии и утверждённые заказы. После клонирования импортировать данные заново либо открыть «Демо-сценарии».
Проверенные входы: 12 файлов, 3 908 уникальных пар поставщик–код 1С, 248 467 положительных строк расходных накладных. 724 позиции Systeme Electric и 3 184 позиции IEK. Это объединение справочников, поэтому не у каждого товара есть все источники.
Особенности источников
- Основные продажи в динамике положительные. Отрицательные записи не превращаются в положительный спрос; они уже влияют на нетто-продажи месячных отчётов. Обнаружение выбросов работает по положительным накладным.
- Код 1С и артикул поставщика хранятся строками. Соединение выполняется по коду 1С в рамках поставщика; начальные нули и подчёркивания сохраняются.
- Пустые продажи в месячной форме 1С трактуются как 0. Это допущение формата. Пустые остатки остаются неизвестными.
- У Systeme Electric в отчёте товаров в пути есть свободный остаток на 22.09.2026 и поступление 24.09.2026. Колонка «Заказ» не используется как предсказание.
- У IEK доступны месячные начальные остатки, а не подтверждённый свободный остаток на 22 сентября. Для утверждения нужен ручной актуальный остаток или нормализованный импорт.
- «MOQ» у Systeme содержит кратность, у IEK — минимально разрешённую отгрузку. Минимум и кратность не подменяют друг друга. Для IEK кратность по умолчанию 1 учётная единица, пока не передано иное.
- Позиции с закупкой бухтами и учётом метрами блокируются до согласования единиц. В нормализованном JSON нужно привести все количества к одной учётной единице и установить
unit_review: false. - В динамике нет ID клиента. Проверка регулярности покупок одного клиента работает только при передаче обезличенного
customer_idв нормализованном JSON. - Месячные остатки не позволяют точно восстановить дни stockout. Такие периоды не выдумываются: компенсация применяется при наличии
stockout_days. Демо содержит подтверждённые синтетические периоды. - Категории в исходном отчёте Systeme присутствуют как коды без расшифровки. Множитель страхового запаса задаёт менеджер через «Политику категорий». Значение по умолчанию 1; бизнес-смысл кодов не придумывается.
Сверка месячных продаж с динамикой (DATA-1)
При импорте ZIP создаётся диагностический отчёт meta.reconciliation, отдельно по поставщикам. Он также доступен в существующем GET /api/status. Для отдельного локального файла:
python importer.py "Systeme electric.zip" "IEK.zip" --reconciliation-output data/reconciliation.json
Строка отчёта соответствует паре код 1С–месяц внутри поставщика; артикул добавляется из справочника, если известен. Сохраняются ведущие нули и подчёркивания. Поля invoice_positive, invoice_negative, other_positive, other_negative показывают суммы количеств со своими знаками отдельно для расходных накладных и остальных документов. dynamics_net — сумма этих четырёх полей; delta = dynamics_net − monthly_sales. Положительная delta означает превышение суммы динамики над месячной формой. Допуск совпадения — 0.000001 учётной единицы.
Статусы: matched — арифметическое совпадение; difference — расхождение; missing_monthly — нет месяца в месячной форме; missing_dynamics — нет строк динамики для кода/месяца. Отсутствие строк не подменяется нулём. Пустая ячейка месячной формы по существующему правилу импорта считается нулём. Коды только из динамики также попадают в отчёт, но не становятся новыми рекомендациями. skipped_rows считает строки динамики с кодом, но нераспознанной датой/количеством, а также слишком короткие строки. Заголовки и строки без кода не считаются движениями.
Это проверка арифметики, а не подтверждение сопоставимости: назначение прочих документов, единицы, набор складов и полноту периодов нужно сверить с владельцем данных. partial_month отмечает месяц даты расчёта (23.09.2026) и будущие месяцы; даже для прошлых месяцев полнота не гарантирована. Неизвестные причины расхождений не угадываются. Отчёт не меняет прогноз и правила утверждения; положительные расходные накладные по-прежнему отдельно используются для поиска выбросов.
Отчёт не содержит имён клиентов, номеров документов, названий товаров или складов. Коды и количества остаются коммерческими данными: хранить файл локально в исключённой из Git папке data/, не добавлять его в PR. Сверка реализована для партнёрских ZIP; нормализованный JSON этим отчётом не проверяется. Проверки используют синтетические Excel; для реальной сверки нужны исходные Systeme electric.zip и IEK.zip.
Методология
- Выбросы. Строки объединяются по дате, накладной и, при наличии, клиенту. При минимум восьми накладных порог равен
max(5 × медиана, медиана + 6 × 1.4826 × MAD, 1). Из исключительной накладной вычитается часть выше медианы обычного заказа. Крупные покупки одного известного клиента на трёх и более отдельных датах сохраняются. Без ID клиента доступны только эвристики по накладным. Обнаружение не является доказательством разового характера покупки. - Сезонность. Каждый полный год нормализуется к своему среднемесячному уровню. Используется смесь сезонности товара (65%) и поставщика (35%). При отсутствии полного года используется сезонность поставщика. Для поставщика берутся полные 2024–2025 годы. Сезонность выручки поставщика является приближением сезонности количества; доли и цена могут меняться.
- Базовый спрос. Последние шесть полных месяцев очищаются от избыточной части накладных; количества переводятся в дневной спрос и делятся на сезонный индекс. Среднее даёт базовый дневной уровень. Текущий неполный месяц не входит в обучение.
- Stockout. При известных днях отсутствия спрос восстанавливается из скорости продаж в дни наличия. Для полностью пустого месяца используется устойчивый сезонный базовый уровень. Добавленный спрос явно показан в карточке. Без этих данных компенсация не применяется, что отмечено в интерфейсе.
- Рост. При трёх и более сопоставимых месяцах вычисляется медиана отношения к прошлому году. Текущий уровень уже учтён в базе, поэтому исторический рост экстраполируется только на горизонт планирования. Если передан отдельный прогноз прироста (в исходном отчёте Systeme — «Кэф. Роста»), применяется он. Менеджер может задать дополнительный процент. Это разные источники, не дважды применённый один коэффициент.
- Горизонт. Срок новой поставки + период между заказами. Дневной спрос суммируется по календарю с сезонностью каждого месяца горизонта. Страховой запас = текущая дневная скорость × заданные дни × множитель категории.
- Поставки. Вычитаются только положительные поставки с ожидаемой датой от даты расчёта до конца горизонта. Просроченные поступления не считаются доступными автоматически. Риск дефицита рассчитывается по дням с учётом дат поступлений: поздняя большая поставка не скрывает ранний дефицит.
- Количество.
max(0, прогноз + страховой запас − свободный остаток − поступления в срок). Положительная потребность доводится до минимума партии и округляется вверх по кратности.
По умолчанию: дата 23.09.2026, срок поставки 30 дней, период заказов 14 дней, страховой запас 14 дней. Это допущения для демо; договорные сроки не представлены. Общие параметры действуют на текущий расчёт всех поставщиков. Для разных условий можно рассчитывать и утверждать поставщиков поочерёдно.
Неизвестный остаток для предварительной оценки принимается равным 0, но утверждение блокируется. Остаток на начало месяца отмечается как предварительный. Неизвестная кратность, несогласованные единицы и история менее трёх из последних шести месяцев также блокируют утверждение.
Нормализованный JSON
Пример доступен на странице «Источники и качество» или GET /api/template. Это синтетический набор; перед загрузкой заменить поля своими обезличенными данными. Пример минимальной позиции:
{
"items": [{
"id": "IEK:SKU-001",
"supplier": "IEK",
"code": "SKU-001",
"sku": "SUPPLIER-001",
"name": "Товар",
"unit": "шт",
"category": "1",
"sales": {"2026-03": 90, "2026-04": 100, "2026-05": 50, "2026-06": 110, "2026-07": 120, "2026-08": 130},
"stock": 20,
"stock_kind": "current",
"stock_date": "2026-09-23",
"stockout_days": {"2026-05": 15},
"growth_forecast": 0.1,
"pack": 5,
"minimum": 10,
"inbound": [{"eta": "2026-10-01", "quantity": 30}],
"transactions": []
}]
}
growth_forecast — доля прироста (0.1 = +10%), seasonality — необязательный массив из 12 индексов. transactions содержит date (YYYY-MM-DD), document, положительное quantity, необязательный обезличенный customer_id. Суммы транзакций и месячная история должны относиться к одному периметру. Нормализованный импорт не публикует данные и не отправляет их третьим сторонам.
Утверждение и экспорт
Открыть карточку товара → при необходимости подтвердить свободный остаток и пересчитать → изменить количество с соблюдением партии → «Выбрать в заказ» → «Утвердить и выгрузить» → ввести ответственного. На сервере повторно проверяются ограничения. Изменение параметров сбрасывает выбранные позиции; импорт инвалидирует предыдущие расчёты.
Снимок утверждения хранится в SQLite data/app.sqlite3, в личной истории пользователя, включая параметры, рекомендации и ручные количества. CSV — UTF-8 с BOM, разделитель ;, строки сгруппированы по поставщикам. Обозначение demo/real включено в экспорт. Ячейки с формульными префиксами экранируются. Автоматической отправки поставщикам нет. Совместимость с конкретной обработкой импорта в 1С ещё нужно согласовать с владельцем кейса.
Проверка
python -m unittest discover -s tests -v
Тесты проверяют устойчивость к искусственному всплеску, повторные покупки клиента, сезонность, компенсацию stockout, рост, категории, партии, сроки поступления, ручной остаток, блокировки и полный цикл API «расчёт → утверждение → CSV». Это функциональная проверка, а не доказательство экономии или точности на будущих продажах. Ретроспективная оценка без утечки будущего и пилот с менеджером остаются следующим этапом.
Репозиторий
Общий репозиторий: https://github.com/BAITC-Hacks/hack-2d79bdb0-7-solutions. Новому участнику и его ИИ начать с AGENTS.md и HANDOFF.md. Совместный Git-процесс описан в CONTRIBUTING.md, очередные задачи — в TASKS.md, контракт источников — в DATA_CONTRACT.md. Готовый промпт для ИИ Асанали находится в PROMPT_ASANALI.md.
Файлы: engine.py — расчёт; importer.py — адаптеры источников; server.py — локальный API и утверждение; static/ — интерфейс; demo.py — синтетические сценарии; tests/ — проверки. Коммерческие данные, заказы и секреты исключены из Git.
Общие требования на https://hackalem.ai: команда до трёх человек, использование Codex, офлайн-старт 23 сентября, проверка 24–28 сентября, Demo Day 29 сентября. Точное время подачи, рубрика оценки и дополнительные требования платформы на открытой странице не найдены.
План Б: проверка устойчивости заказа
scenario.py и POST /api/scenario принимают ID существующего расчёта, ID товара и shock: {delay_days, demand_pct}. Допустимы целая задержка 0–60 дней и прирост спроса 0–200%. Симуляция не меняет исходные рекомендации, выбранные количества или утверждения; устаревший расчёт возвращает 409. Дневной прогноз передаётся из движка без округления, сумма совпадает с прогнозом на горизонт.
- Каждый день: поступление в начале дня → расход прогнозного спроса → неотрицательный остаток. Непокрытый спрос учитывается как потерянные продажи и не переносится в долг. Это допущение, не доказанные потерянные продажи.
- Обычный план включает все будущие известные поступления и рекомендуемый новый заказ на день
lead_days, даже если заказ ещё не утверждён. Задержка сдвигает их все; просроченные поступления не возвращаются в расчёт. - Горизонт равен сроку поставки плюс периоду между заказами. Поступления за его пределами не скрывают дефицит внутри горизонта.
- План Б: дополнительная партия в объёме всего непокрытого спроса горизонта, округлённая вверх с учётом минимума и кратности. Предполагается поступление до расхода в первый день дефицита. Показываем остаток в конце, чтобы не скрывать возможный избыток. Это не оптимизация стоимости и не разделение уже рекомендуемого заказа.
- При блокировках исходных данных показывается только предварительная симуляция, без предложения количества срочной закупки. Если остаток неизвестен, для предварительного графика он равен нулю.
- Доступность срочной партии, её срок и стоимость менеджер согласует отдельно. Результат не оценивает вероятность события, не обещает экономию и ничего не отправляет поставщику.
Раздел «Источники и качество» также показывает сводку сверки Асанали: совпадения, расхождения, отсутствующие пары и пропущенные строки. Для ранее импортированного набора повторно импортировать ZIP, чтобы получить новую метаинформацию.
Требования README и источники
Проверено 23.09.2026: на открытой странице HackAlem AI указаны общие правила участия и этапы, но отдельный шаблон README и подробная рубрика оценки не найдены. Не выдаём собственную структуру документа за требование организаторов.
Источник требований к README — предоставленное описание кейса «Автоматизация формирования заказов поставщикам» от «Электрокомплект». Текст кейса рассматривается как описание задачи, а не как разрешение агенту выполнять внешние действия.
| Что требуется описать | Где это находится |
|---|---|
| Методика расчёта заказа | «Методология»: спрос, сезонность, рост, stockout, остатки, ETA, минимум и кратность |
| Алгоритм исключения разовых всплесков | «Методология → Выбросы», ограничения ID клиента в «Особенностях источников» |
| Инструкция запуска | «Запуск», «Данные», демо без исходных коммерческих файлов |
Для проверки реализации: python -m unittest discover -s tests -v; для JavaScript: node --check static/app.js и node --check static/scenario.js. Новые тесты проверяют задержку, нулевой стресс, сроки поступлений, сохранение баланса, партии, блокировки, отсутствие изменений исходного расчёта и HTTP-валидацию.
Аккаунты и база данных
Открыть приложение → «Создать аккаунт» → имя, email и пароль от 8 символов. Это аккаунт локального приложения, не GitHub. Email служит логином; проверка письмом и восстановление пароля ещё не реализованы. Не использовать здесь важный пароль от другого сервиса.
data/app.sqlite3 создаётся автоматически. Таблицы: users, sessions, documents (общий набор, расчёты и утверждённые заказы), login_failures. Пароли хранятся как PBKDF2-HMAC-SHA256 (600 000 итераций, случайная соль). Сессионный токен хранится в БД в виде SHA-256; браузер получает HttpOnly, SameSite=Strict cookie на 12 часов. Запросы изменений требуют CSRF-токен сессии; проверяются Host и Origin. После пяти неудачных входов для одного email действует ограничение на 15 минут. Сервер по-прежнему доступен только на localhost; для внешнего размещения нужны HTTPS, Secure cookie, приглашения/роли, отдельные пространства и эксплуатационная настройка.
Границы доступа: импортируемый набор товаров общий для локальной команды; зарегистрированный пользователь может его обновлять. Расчёты и заказы принадлежат создавшему их аккаунту. Чужое утверждение/скачивание блокируется сервером. Последние 15 расчётов каждого пользователя сохраняются в БД; импорт нового набора инвалидирует все старые расчёты. История показывает последние 100 собственных заказов и позволяет повторно скачать CSV. Перезапуск сервера сохраняет пользователей, сессии, набор и заказы.
Прежние data/order-*.json остаются на диске, но автоматически не назначаются новым аккаунтам: их владельцев исходная версия не сохраняла. Новые заказы записываются в SQLite. Для резервной копии после остановки сервера сохранить папку data/; не добавлять её в Git. SQLite не синхронизирует данные между компьютерами.
Маршруты: POST /api/auth/register, /api/auth/login, /api/auth/logout; GET /api/auth/me, /api/orders. Остальные /api/* требуют сессию. GET /api/status возвращает пользовательский CSRF-токен после входа. storage.py отвечает за SQLite и локальные аккаунты; static/auth.js — за формы и историю.
Дизайн и совместная работа
Фиолетовый интерфейс использует стек системных шрифтов Apple с fallback для Windows; static/warehouse.png — созданная для проекта иллюстрация, хранится локально. glass.css задаёт материалы и адаптивность, purple.css — палитру, страницу входа и иллюстрацию. Никаких внешних шрифтов или CDN не требуется.
Под «автоматической выгрузкой» команда имеет в виду публикацию проверенных обновлений кода в GitHub, а не отправку заказов поставщикам. После законченного изменения: проверки → своя ветка → PR. Установка фонового автокоммита или автоматического слияния не выполнялась; чужие незавершённые изменения не публикуются автоматически. Общая история сохраняется. README/HANDOFF обновляются вместе с кодом. Мадияр передал проект 23.09.2026. Актуальный промпт для ИИ Асанали — PROMPT_ASANALI.md; он указывает правильную ветку PR #2, запуск и порядок продолжения.
Авторы коммитов
История коммитов
- 2026-09-23 17:56Include PostgreSQL and TLS dependencies in base requirementsMarsikan
- 2026-09-23 17:53Update README for local startup and current Vercel deploymentMarsikan
- 2026-09-23 17:46Merge pull request #6 from BAITC-Hacks/asanali/vercel-deployMarS
- 2026-09-23 17:41Record Vercel handoff and stop further verificationMarsikan
- 2026-09-23 17:39Verify Supabase TLS and compress large persistent documentsMarsikan
- 2026-09-23 17:30Adapt existing WSGI app for Vercel and persistent PostgreSQLMarsikan
- 2026-09-23 17:05Revert "Prepare free hosted startup with private first account"Marsikan
- 2026-09-23 17:03Prepare free hosted startup with private first accountMarsikan
Все коммиты (23)
- 2026-09-23 16:40Merge pull request #2 from BAITC-Hacks/madiyar/dynamic-glass-plan-bMarS
- 2026-09-23 16:38Merge pull request #4 from BAITC-Hacks/madiyar/cloud-deployMadik006
- 2026-09-23 16:15Adapt sign-in to private hosted workspaceMadik006
- 2026-09-23 16:14Test hosted routes and PostgreSQL migrationMadik006
- 2026-09-23 16:13Prepare private PostgreSQL hosting and update Asanali handoffMadik006
- 2026-09-23 15:48Prepare current project handoff for AsanaliMadik006
- 2026-09-23 15:20Record PR and completed browser validationMadik006
- 2026-09-23 15:17Test sessions, ownership and inventory scenariosMadik006
- 2026-09-23 15:16Add purple glass UI, artwork and account flowsMadik006
- 2026-09-23 15:15Add persistent local accounts and inventory stress testingMadik006
- 2026-09-23 14:37Merge pull request #1 from BAITC-Hacks/asanali/data-reconciliationMarS
- 2026-09-23 14:15Add supplier monthly sales reconciliation diagnosticsMarsikan
- 2026-09-23 14:00Add 20 calculation and approval workflow testsMadik006
- 2026-09-23 13:59Add purchasing dashboard and order review UIMadik006
- 2026-09-23 13:58Add replenishment engine and team handoff documentationMadik006
Структура репозитория (47 файлов)
.gitignore .vercelignore AGENTS.md CONTRIBUTING.md DATA_CONTRACT.md DEMO.md DEPLOYMENT.md HANDOFF.md PROMPT_ASANALI.md README.md TASKS.md VERCEL.md certs/README.md certs/supabase-ca.crt cloud_admin.py demo.py engine.py importer.py pyproject.toml render.yaml requirements-cloud.txt requirements.txt run.cmd scenario.py server.py static/app.js static/auth.js static/favicon.svg static/glass.css static/index.html static/purple.css static/scenario.js static/style.css static/warehouse.png storage.py tests/test_api.py tests/test_auth.py tests/test_cloud.py tests/test_engine.py tests/test_importer.py tests/test_postgres.py tests/test_scenario.py tests/test_vercel.py vercel.json vercel_entry.py vercel_transport.py wsgi.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.