Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
812cdb5
Add project documentation, Qwen context, and MIT license
lookson111 Apr 6, 2026
16a42cd
Update README with MIT license info
lookson111 Apr 6, 2026
9a9e672
Add comprehensive project issues audit to QWEN.md
lookson111 Apr 6, 2026
d091255
Объединить AGENTS.md и QWEN.md в единый файл контекста для AI-агентов
lookson111 Aug 3, 2026
61c4cf2
Добавить setup.sh развёртывания и разрешённые команды для AI-агентов
lookson111 Aug 3, 2026
d602899
Покрыть тестами person и press: модели, формы, сервисы, view
lookson111 Aug 3, 2026
0783a07
Зафиксировано фактическое поведение спорных участков кода, добавлено …
lookson111 Aug 3, 2026
817c038
Скрипт run_tests.sh для запуска тестов без настройки PostgreSQL
lookson111 Aug 3, 2026
981998c
Убрать отладочные print() из view, засорявшие вывод и логи
lookson111 Aug 3, 2026
38847a6
Убрать SQLite из прогона тестов: run_tests.sh поднимает временный Pos…
lookson111 Aug 3, 2026
69d74f3
Разделить развёртывание setup.sh на режимы dev и prod: разные настрой…
lookson111 Aug 3, 2026
01e2eed
Добавить развёртывание в Docker: compose с PostgreSQL и настройки из …
lookson111 Aug 3, 2026
4e29db4
Синхронизировать пароль БД при повторном запуске setup.sh: иначе мигр…
lookson111 Aug 3, 2026
57cd15d
Добавить шаблон local_settings.example.py и перевести setup.sh на его…
lookson111 Aug 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[run]
source =
person
press
helpers
omit =
*/migrations/*
*/tests.py
config/*
manage.py
person/signals.py

[report]
show_missing = True
23 changes: 23 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Контекст сборки Docker-образа party_crm
.git/
.gitignore
venv/
.venv/
__pycache__/
*.pyc
.coverage
.coverage.*
htmlcov/

# Секреты и локальные настройки в образ не попадают
.env
config/local_settings.py

# Артефакты, не нужные в контейнере
staticfiles/
deploy/
docs/
.gigacode/
.vscode/
run_tests.sh
setup.sh
32 changes: 32 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Настройки запуска party_crm в Docker.
# Скопируйте файл в .env (cp .env.example .env) и заполните значения.
# .env в .gitignore — не коммитить.

# Обязательные
SECRET_KEY=change-me-long-random-string
DB_PASSWORD=change-me-db-password

# База данных (дефолты совпадают с setup.sh; в контейнере DB_HOST=db задаёт compose)
#DB_NAME=party_crm_db
#DB_USER=party_crm
#DB_PORT=5432

# Режим
#DEBUG=0
# Домены через запятую
ALLOWED_HOSTS=localhost,127.0.0.1
# HTTPS=1 включает SECURE_SSL_REDIRECT, secure-куки и HSTS (включайте за TLS-прокси)
#HTTPS=0

# Число воркеров gunicorn
#GUNICORN_WORKERS=3

# Почта для отправки отчётов
EMAIL_HOST=smtp.example.com
EMAIL_PORT=587
EMAIL_HOST_USER=your-email@example.com
EMAIL_HOST_PASSWORD=your-email-password
#EMAIL_USE_TLS=1

# Получатели месячного отчёта, адреса через запятую
REPORT_MONTH_EMAIL=recipient@example.com
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,9 @@ package.json
node_modules
*.sqlite3
config/local_settings.py
static/admin
static/admin
staticfiles/
deploy/

# Documentation (auto-generated)
docs/django_and_database.md
242 changes: 242 additions & 0 deletions AGENTS.md

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Образ party_crm: Django + gunicorn. Запуск — через docker-compose.yml.
FROM python:3.12-slim

ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1

WORKDIR /app

# Зависимости отдельным слоем, чтобы кэшировались при изменении кода
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

ENTRYPOINT ["docker/entrypoint.sh"]
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
212 changes: 211 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,214 @@
# party_crm
CRM для партийной работы РПР

CRM для партийной работы РПР (Российская рабочая партия) — Московская городская организация.

## Описание

Система учёта распространения партийной печати. Позволяет фиксировать:

- Где, когда и сколько газет распространялось
- Какие партийные члены и сочувствующие участвовали в распространении
- Сколько экземпляров было распространено на каждом предприятии
- Генерация отчётов в формате Excel по почте

## Технологии

- **Backend**: Django 4.2, Python
- **База данных**: PostgreSQL (psycopg3)
- **Frontend**: HTMX, Alpine.js, Bootstrap 5, Select2, jQuery
- **Отчёты**: XlsxWriter
- **Сервер**: Gunicorn

## Установка

### В Docker

Самый простой способ запустить CRM — Docker Compose (приложение + PostgreSQL):

1. Создайте файл окружения и заполните его:

```bash
cp .env.example .env
# отредактируйте .env: SECRET_KEY, DB_PASSWORD, ALLOWED_HOSTS, EMAIL_*
```

2. Соберите и запустите:

```bash
docker compose up --build -d
```

При старте контейнер сам применяет миграции и собирает статику
(см. `docker/entrypoint.sh`). CRM доступна на `http://localhost:8000`.

3. Создайте суперпользователя:

```bash
docker compose exec app python manage.py createsuperuser
```

Данные PostgreSQL хранятся в volume `pgdata`. Настройки контейнер читает из
переменных окружения (`.env`) через `config/docker_settings.py` — он
подключается автоматически, если нет `config/local_settings.py`.

### Для разработки

Быстрый способ — скрипт `setup.sh` (Debian/Ubuntu): установит системные пакеты,
PostgreSQL-пользователя и БД, venv с зависимостями, сгенерирует
`config/local_settings.py` (режим разработчика, `DEBUG=True`) и применит миграции:

```bash
./setup.sh # или явно: ./setup.sh dev
```

Либо вручную:

1. Клонируйте репозиторий:

```bash
git clone <repository-url>
cd party_crm
```

2. Создайте виртуальное окружение и установите зависимости:

```bash
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```

3. Создайте файл `config/local_settings.py` по шаблону и заполните его:

```bash
cp config/local_settings.example.py config/local_settings.py
# отредактируйте: SECRET_KEY, DATABASES, EMAIL_*, REPORT_MONTH_EMAIL
```

4. Выполните миграции:

```bash
python manage.py migrate
```

5. Создайте суперпользователя:

```bash
python manage.py createsuperuser
```

6. Запустите сервер разработки:

```bash
python manage.py runserver
```

### Для продакшена

Используйте prod-режим `setup.sh`:

```bash
APP_ALLOWED_HOSTS="crm.example.com,www.crm.example.com" ./setup.sh prod
```

Отличия от режима разработчика:

- `config/local_settings.py` генерируется с `DEBUG=False`, `ALLOWED_HOSTS`
(из `APP_ALLOWED_HOSTS`, домены через запятую), `STATIC_ROOT` и
HTTPS-hardening-настройками (`SECURE_SSL_REDIRECT`, secure-куки, HSTS —
отключаются переменной `HTTPS=0`);
- выполняется `collectstatic` в `staticfiles/`;
- генерируются `deploy/gunicorn.conf.py` и `deploy/party-crm.service`
(systemd-юнит с реальными путями; команды установки печатаются в конце
скрипта, сам юнит скрипт не устанавливает).

После завершения: заполните `EMAIL_*` в `config/local_settings.py`, установите
systemd-юнит и настройте nginx как reverse proxy с TLS.

## Использование

### Авторизация

Вход в систему осуществляется по email (не по имени пользователя). Пароль задаётся при создании учётной записи.

### Основные разделы

- **Распространение** — создание и просмотр записей о распространении газет
- **Населённые пункты** — управление справочником населённых пунктов
- **Предприятия** — управление списком предприятий/точек распространения
- **Газеты** — каталог газет и их номеров
- **Отчёты** — генерация и отправка Excel-отчётов по почте

### Генерация отчётов

Отчёт можно сгенерировать двумя способами:

1. Через веб-интерфейс: перейдите в раздел `report/`
2. Через командную строку:

```bash
python manage.py send_report
```

Отчёт включает три листа:
- **Общие данные** — все распространения с датами, предприятиями, газетами и количеством
- **Распространители** — разбивка по каждому распространителю по месяцам
- **Предприятия** — разбивка по каждому предприятию по месяцам

## Структура проекта

```
party_crm/
├── config/ # Настройки Django, URL-маршруты, WSGI/ASGI
│ ├── settings.py # Основные настройки
│ └── urls.py # Корневой URL-конфиг
├── person/ # Пользовательская модель пользователя, аутентификация
│ ├── models.py # Person (пользователь), PartyOrganization
│ └── views.py # Вход, выход, профиль
├── press/ # Основная бизнес-логика
│ ├── models.py # Newspaper, Town, FactoryPoint, Distribution и др.
│ ├── views.py # CRUD распространений, отчёты, справочники
│ ├── services/ # Бизнес-логика: distributions, report, mail
│ └── management/ # Команды управления (send_report)
├── helpers/ # Вспомогательные утилиты (name_normalizer)
├── templates/ # Глобальные базовые шаблоны
└── static/ # Статические файлы (CSS, JS)
```

## Команды управления

```bash
# Запуск сервера разработки
python manage.py runserver

# Применение миграций
python manage.py migrate

# Создание суперпользователя
python manage.py createsuperuser

# Отправка месячного отчёта
python manage.py send_report

# Запуск тестов
python manage.py test
```

## Разработка

### Особенности

- Используется HTMX для динамического обновления страниц без перезагрузки
- HTMX-представления имеют префикс `hx_` в названиях методов
- Все пользовательские строки на русском языке (локаль `ru-ru`)
- Часовой пояс: `Europe/Moscow`

### Код-стайл

- Импорты: стандартная библиотека → Django → сторонние → локальные
- snake_case для функций/переменных, PascalCase для моделей
- URL: kebab-case с префиксами (`new-distrib/`, `hx-add-party-member/`)

## Лицензия

Проект распространяется под лицензией MIT. Подробности см. в файле [LICENSE](LICENSE).
Loading