deystvuy-kak-senior-full-sta/README.md

350 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# BI-дашборд для оценки эффективности автобаз
Корпоративный веб-сервис для мониторинга и анализа работы транспортных подразделений.
## 📋 Возможности
- **Многофакторный рейтинг** подразделений на основе 5 KPI
- **Авторизация и RBAC** (роли: админ, руководитель, бухгалтер, водитель)
- **Экспорт отчётов** для обоснования бюджета
- **Абстракция данных** (легко переключиться с Google Sheets на ERP API)
- **Политика конфиденциальности** на всех экранах
## 🏗 Архитектура
### Паттерн Repository (DataFetcher)
```
┌─────────────────────────────────────────┐
│ DataFetcher (Interface) │
│ - get_fleet_data() -> DataFrame │
│ - get_requests_data() -> DataFrame │
│ - get_accidents_data() -> DataFrame │
│ - get_maintenance_data() -> DataFrame │
│ - get_fuel_data() -> DataFrame │
│ - get_employees_data() -> DataFrame │
└─────────────────────────────────────────┘
▲
┌───────────┼───────────┐
│ │ │
┌───────┴────┐ ┌───┴────────┐ ┌┴──────────────┐
│MockData │ │GoogleSheets│ │ApiFetcher │
│Fetcher │ │Fetcher │ │(будущая ERP) │
└────────────┘ └────────────┘ └───────────────┘
```
**Преимущества:**
- Код бизнес-логики (`KPICalculator`) не зависит от источника данных
- Для подключения ERP нужно лишь создать класс `ApiFetcher` с теми же методами
- Тестирование на mock-данных без подключения к внешним сервисам
## 📁 Структура проекта
```
autobase-bi/
├── app.py # Главное приложение Streamlit
├── data_fetcher.py # Абстракция доступа к данным
├── requirements.txt # Зависимости Python
├── .env.example # Шаблон переменных окружения
├── service_account.json # Ключ Google Service Account (не в git!)
└── README.md # Эта документация
```
## 🚀 Быстрый старт
### 1. Установка зависимостей
```bash
pip install -r requirements.txt
```
### 2. Настройка окружения
Скопируйте `.env.example` в `.env`:
```bash
cp .env.example .env
```
Отредактируйте `.env` при необходимости (для демо можно оставить значения по умолчанию).
### 3. Запуск приложения
```bash
streamlit run app.py
```
Приложение откроется по адресу: http://localhost:8501
### 4. Вход в систему
Используйте тестовые учётные данные:
| Логин | Пароль | Роль | Права доступа |
|-------|--------|------|---------------|
| admin | admin123 | Администратор | Полный доступ |
| manager | manager123 | Руководитель | Просмотр + экспорт |
| accountant | accountant123 | Бухгалтер | Финансы + экспорт |
| driver | driver123 | Водитель | Только свои данные |
## 🔧 Настройка Google Sheets API
### Шаг 1: Создание сервиса в Google Cloud
1. Откройте [Google Cloud Console](https://console.cloud.google.com/)
2. Создайте новый проект или выберите существующий
3. Включите **Google Sheets API**:
- Перейдите в "APIs & Services" → "Library"
- Найдите "Google Sheets API" и нажмите "Enable"
### Шаг 2: Создание сервисного аккаунта
1. Перейдите в "APIs & Services" → "Credentials"
2. Нажмите "Create Credentials" → "Service Account"
3. Заполните данные:
- Service account name: `autobase-bi-service`
- Service account ID: создастся автоматически
- Role: **Viewer** (только чтение)
4. Нажмите "Create and Continue"
### Шаг 3: Генерация ключа
1. На странице сервисного аккаунта перейдите во вкладку "Keys"
2. "Add Key" → "Create new key"
3. Выберите формат **JSON**
4. Скачайте файл и сохраните как `service_account.json` в корне проекта
### Шаг 4: Предоставление доступа к таблице
1. Откройте вашу Google Таблицу
2. Нажмите кнопку "Поделиться" (Share)
3. Вставьте email сервисного аккаунта (вида `autobase-bi-service@project-id.iam.gserviceaccount.com`)
4. Дайте права **Читатель** (Viewer)
5. Скопируйте ID таблицы из URL (между `/d/` и `/edit`)
### Шаг 5: Настройка .env
Отредактируйте `.env`:
```env
GOOGLE_SERVICE_ACCOUNT_KEY_PATH=./service_account.json
GOOGLE_SHEET_ID=ваш_id_таблицы_здесь
```
### Шаг 6: Структура Google Таблицы
Создайте листы со следующими названиями и колонками:
**Лист "Автопарк":**
```
vehicle_id | vehicle_type | department | status | year | mileage | purchase_cost
V001 | Грузовой | Автобаза №1 | В работе | 2022 | 75000 | 2500000
```
**Лист "Заявки":**
```
request_id | department | date | status | fulfilled | vehicle_id
R0001 | Автобаза №1 | 2024-01-15 | Исполнено | 1 | V001
```
**Лист "ДТП_ПДД":**
```
incident_id | date | vehicle_id | driver_id | type | severity | fine_amount
I001 | 2024-02-10 | V001 | D005 | ДТП | Средний | 15000
```
**Лист "ТО_Ремонты":**
```
maintenance_id | vehicle_id | date | type | downtime_days | cost
M0001 | V001 | 2024-01-20 | Плановое ТО | 2 | 25000
```
**Лист "ГСМ_Финансы":**
```
vehicle_id | date | fuel_liters | fuel_cost | planned_cost | actual_cost
V001 | 2024-01-15 | 250 | 12500 | 12000 | 12500
```
**Лист "Сотрудники":**
```
employee_id | name | department | position | license_category
D001 | Иванов А.А. | Автобаза №1 | Водитель | C
```
### Шаг 7: Переключение на Google Sheets
В приложении выберите в боковой панели:
- Источник данных: **Google Sheets**
Или измените `app.py`:
```python
# Было (демо):
st.session_state.data_fetcher = MockDataFetcher()
# Стало (Google Sheets):
from data_fetcher import GoogleSheetsFetcher
st.session_state.data_fetcher = GoogleSheetsFetcher(
service_account_path=os.getenv('GOOGLE_SERVICE_ACCOUNT_KEY_PATH'),
sheet_id=os.getenv('GOOGLE_SHEET_ID')
)
```
## 📊 Метрики и KPI
### 1. Коэффициент исполнения заявок (25%)
```
Исполнено заявок / Всего заявок × 100%
```
### 2. Коэффициент использования парка (КИП) (20%)
```
(Всего ТС - В ремонте) / Всего ТС × 100%
```
### 3. Безопасность (20%)
```
100 - (ДТП × 5 + Нарушения × 2) / Всего ТС × 10
```
### 4. Эксплуатация и ремонты (15%)
```
100 - (Простой дней / Всего ТС) × 2
```
### 5. Финансы и ГСМ (20%)
```
Перерасход: (Факт - План) / План × 100%
Стоимость 1 км: Общие расходы / Пробег × 1000
```
### Сводный рейтинг
```
Рейтинг = KPI1×0.25 + KPI2×0.20 + KPI3×0.20 + KPI4×0.15 + KPI5×0.20
```
## 🔐 Безопасность
### Ролевая модель (RBAC)
| Роль | Просмотр всех | Экспорт | Финансы | Управление |
|------|---------------|---------|---------|------------|
| Администратор | ✅ | ✅ | ✅ | ✅ |
| Руководитель | ✅ | ✅ | ✅ | ❌ |
| Бухгалтер | ❌ | ✅ | ✅ | ❌ |
| Водитель | ❌ | ❌ | ❌ | ❌ |
### Продакшен-рекомендации
1. **Замените хардкод логинов** на LDAP/Active Directory
2. **Настройте HTTPS** через reverse proxy (nginx)
3. **Добавьте логирование** действий пользователей
4. **Регулярно ротируйте** токены и ключи
```python
# Пример LDAP авторизации (заменить в check_credentials)
import ldap
def ldap_auth(username, password):
conn = ldap.initialize('ldap://your-domain.local')
try:
conn.simple_bind_s(f'{username}@domain.local', password)
return True
except:
return False
```
## 📈 Экспорт отчёта для бюджета
1. Войдите под ролью **admin** или **manager**
2. Перейдите в раздел **"💰 Бюджет 2027"**
3. Нажмите **"📥 Скачать отчёт (CSV)"**
Отчёт содержит:
- Текущие расходы за 2024 год
- Прогноз на 2027 год с учётом инфляции и износа
- Рекомендуемый бюджет
- Потребность в обновлении автопарка
## 🔄 Подключение ERP API (Фаза 2)
Для перехода с Google Sheets на ERP:
### 1. Создайте класс ApiFetcher
```python
# data_fetcher.py
class ApiFetcher(DataFetcher):
def __init__(self, api_base_url: str, api_token: str):
self.api_base_url = api_base_url
self.api_token = api_token
def get_fleet_data(self) -> pd.DataFrame:
response = requests.get(
f'{self.api_base_url}/fleet/vehicles',
headers={'Authorization': f'Bearer {self.api_token}'}
)
return pd.DataFrame(response.json())
# Реализуйте остальные 5 методов аналогично
```
### 2. Обновите app.py
```python
from data_fetcher import ApiFetcher
st.session_state.data_fetcher = ApiFetcher(
api_base_url=os.getenv('ERP_API_URL'),
api_token=os.getenv('ERP_API_TOKEN')
)
```
### 3. Добавьте в .env
```env
ERP_API_URL=https://erp.your-company.local/api/v1
ERP_API_TOKEN=your_token_here
```
**Никаких изменений в бизнес-логике не требуется!**
## 🛠 Troubleshooting
### Ошибка "ModuleNotFoundError"
```bash
pip install -r requirements.txt --upgrade
```
### Ошибка Google API "credentials invalid"
- Проверьте путь к `service_account.json`
- Убедитесь, что сервисный аккаунт имеет доступ к таблице
- Проверьте ID таблицы в `.env`
### Приложение не запускается
```bash
# Проверьте версию Python (требуется 3.8+)
python --version
# Пересоздайте виртуальное окружение
python -m venv venv
source venv/bin/activate # Linux/Mac
# или
venv\Scripts\activate # Windows
pip install -r requirements.txt
```
### Streamlit показывает кэш
- Очистите кэш: `st.cache_resource.clear()`
- Перезапустите приложение
## 📄 Лицензия
Внутренний корпоративный сервис. Не для публикации.
---
**⚠️ Политика конфиденциальности:**
Внимание: информация носит строго конфиденциальный характер. Я передаю данные для обработки, но требую хранить их в безопасности и не передавать третьим лицам согласно закону. Запрещено размещение в открытом доступе.