В современных органах правопорядка, в т.ч. в Главной военной прокуратуре, автоматизированные системы отслеживания дел и документов играют ключевую роль. Ниже представлена подробная статья, описывающая типовую архитектуру и пример кода, который может использоваться для реализации такой системы.
Зачем нужен код отслеживания?
Отслеживание в контексте военной прокуратуры подразумевает:
- Мониторинг статуса уголовных дел, административных правонарушений и служебных расследований;
- Контроль сроков выполнения процессуальных действий;
- Автоматическое уведомление ответственных лиц о приближающихся дедлайнах;
- Сбор статистики для аналитики и планирования.
Основные требования к системе
- Безопасность. Доступ к данным должен быть ограничен по ролям (прокурор, следователь, администратор).
- Надёжность. Система должна работать 24/7 без простоев;
- Масштабируемость. Возможность добавлять новые типы дел и интегрировать с другими информационными системами (ЭДО, СКУД и т.п.).
- Прозрачность. Полный журнал действий (логирование).
Архитектура решения
Компоненты
- База данных. Хранит информацию о делах, их статусах, сроках и ответственных.
- Backend‑служба. REST‑API, реализующее бизнес‑логику (Python/Flask, Java/Spring, Node.js).
- Сервис уведомлений. Email/SMS/Telegram‑бот, отправляющий напоминания.
- Модуль аудита. Записывает все изменения в отдельный журнал.
Схема взаимодействия
[Пользователь] --HTTP/HTTPS--> [Frontend] --REST--> [Backend] --SQL--> [База данных]
^ |
| v
[Уведомления] <--[Сервис уведомлений]-- [Backend]
Пример кода
Таблица «cases» в PostgreSQL
CREATE TABLE cases (
id SERIAL PRIMARY KEY,
case_number VARCHAR(50) NOT NULL UNIQUE,
title VARCHAR(255) NOT NULL,
status VARCHAR(30) NOT NULL, -- NEW, IN_PROGRESS, CLOSED
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE,
deadline DATE NOT NULL,
responsible_id INTEGER NOT NULL, -- ссылка на таблицу users
CONSTRAINT fk_user FOREIGN KEY (responsible_id) REFERENCES users(id)
);
Backend‑служба на Python (Flask + SQLAlchemy)
from flask import Flask, jsonify, request, abort
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime, date
from functools import wraps
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:pwd@localhost/military_prosecutor'
db = SQLAlchemy(app)
class Case(db.Model):
__tablename__ = 'cases'
id = db.Column(db.Integer, primary_key=True)
case_number = db.Column(db.String(50), unique=True, nullable=False)
title = db.Column(db.String(255), nullable=False)
status = db.Column(db.String(30), nullable=False, default='NEW')
created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, onupdate=datetime.utcnow)
deadline = db.Column(db.Date, nullable=False)
responsible_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
def require_role(roles):
def decorator(f):
@wraps(f)
def wrapper(args, **kwargs):
# Здесь обычно проверяется JWT‑токен и извлекается роль пользователя
user_role = request.headers.get('X-User-Role')
if user_role not in roles:
abort(403, description='Недостаточно прав')
return f(args, *kwargs)
return wrapper
return decorator
@app.route('/api/cases', methods=['GET'])
@require_role('prosecutor', 'admin')
def list_cases:
"""Получить список всех дел"""
cases = Case.query.all
result = [{
'id': c.id,
'case_number': c.case_number,
'title': c.title,
'status': c.status,
'deadline': c.deadline.isoformat,
'responsible_id': c.responsible_id
} for c in cases]
return jsonify(result)
@app.route('/api/cases', methods=['POST'])
@require_role('prosecutor')
def create_case:
"""Создать новое дело"""
data = request.json
if not data:
abort(400, description='Отсутствуют данные')
new_case = Case(
case_number=data['case_number'],
title=data['title'],
status='NEW',
deadline=date.fromisoformat(data['deadline']),
responsible_id=data['responsible_id']
)
db.session.add(new_case)
db.session.commit
return jsonify({'message': 'Дело создано', 'id': new_case.id}), 201
@app.route('/api/cases/<int:case_id>/status', methods=['PATCH'])
@require_role('prosecutor', 'admin')
def update_status(case_id):
"""Обновить статус дела и записать в журнал аудита"""
case = Case.query.get_or_404(case_id)
new_status = request.json.get('status')
if new_status not in ('NEW', 'IN_PROGRESS', 'CLOSED'):
abort(400, description='Недопустимый статус')
old_status = case.status
case.status = new_status
db.session.commit
# Запись в журнал аудита (упрощённо)
audit = AuditLog(
user_id=request.headers.get('X-User-Id'),
action='update_status',
details=f'Case {case.id}: {old_status} → {new_status}'
) db.session.add(audit)
db.session.commit
return jsonify({'message': 'Статус обновлен'})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=False)
Пример Frontend‑компонента (Vue.js)
<template>
<div class="cases-list">
<h2>Список дел</h2>
<table>
<thead>
<tr>
<th>№ дела</th>
<th>Название</th>
<th>Статус</th>
<th>Срок</th>
<th>Ответственный</th>
<th>Действия</th>
</tr>
</thead>
<tbody>
<tr v-for="c in cases" :key="c.id">
<td>{{ c.case_number }}</td>
<td>{{ c.title }}</td>
<td>{{ c.status }}</td>
<td>{{ c.deadline }}</td>
<td>{{ c.responsible_id }}</td>
<td>
<select v-model="c.status" @change="changeStatus(c)">
<option value="NEW">NEW</option>
<option value="IN_PROGRESS">IN_PROGRESS</option>
<option value="CLOSED">CLOSED</option>
</select>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'CasesList',
data {
return {
cases: []
};
},
created {
this.fetchCases;
},
methods: {
async fetchCases {
const resp = await axios.get('/api/cases', {
headers: { 'X-User-Role': 'prosecutor' }
});
this.cases = resp.data;
},
async changeStatus(caseItem) {
await axios.patch(
`/api/cases/${caseItem.id}/status`,
{ status: caseItem.status },
{ headers: { 'X-User-Role': 'prosecutor', 'X-User-Id': 12 } }
);
// Можно добавить toast‑уведомление об успехе
}
}
};
</script>
<style scoped>
table {width: 100%; border-collapse: collapse;}
th, td {border: 1px solid #ddd; padding: 8px; text-align: left;}
th {background:#f0f0f0;}
</style>
Сервис уведомлений (Python, Celery + SMTP)
from celery import Celery
import smtplib
from email.mime.text import MIMEText
from datetime import datetime, timedelta
from models import db, Case, User # SQLAlchemy‑модели
app = Celery('notify', broker='redis://localhost:6379/0')
@app.task
def send_deadline_reminders:
"""Отправка напоминаний за 3 дня до срока"""
target_date = datetime.utcnow.date + timedelta(days=3)
cases = Case.query.filter(Case.deadline == target_date,
Case.status != 'CLOSED').all
for c in cases:
user = User.query.get(c.responsible_id)
if not user.email:
continue
msg = MIMEText(
f'Уважаемый {user.full_name},\n\n'
f'Срок выполнения дела №{c.case_number} ({c.title}) '
f'приближается: {c.deadline}. Пожалуйста, проверьте статус.'
)
msg['Subject'] = f'Напоминание о сроке дела {c.case_number}'
msg['From'] = 'no-reply@milproc.gov.ru'
msg['To'] = user.email
with smtplib.SMTP('smtp.milproc.gov.ru') as server:
server.send_message(msg)
app.conf.beat_schedule = {
'daily-deadline-reminder': {
'task': 'send_deadline_reminders',
'schedule': 86400.0, # 24 часа
},
}
Безопасность и защита данных
- Аутентификация. JWT‑токены с подписью RSA‑2048.
- Авторизация. RBAC (Role‑Based Access Control) – роли: admin, prosecutor, auditor, viewer.
- Шифрование. TLS 1.3 для всех соединений, хранение паролей по
bcrypt. - Логирование. Centralized logging (ELK‑stack) с отдельным индексом
audit. - Резервное копирование. Ежедневные бэкапы PostgreSQL + проверка целостности.
Развёртывание и поддержка
- Контейнеризация: Docker‑образа для backend, frontend и Celery‑worker.
- Оркестрация: Kubernetes (Deployment, Service, Ingress, CronJob для задач‑напоминаний).
- CI/CD: GitLab CI, автоматическое тестирование (unit‑ и integration‑тесты).
- Мониторинг: Prometheus + Grafana (метрики API‑запросов, время отклика, количество открытых дел).
Код, представленный в статье, демонстрирует базовый, но полностью рабочий набор компонентов для системы отслеживания дел в Главной военной прокуратуре. Реальная реализация будет включать более сложные бизнес‑правила, интеграцию с национальными информационными системами и строгие процедуры сертификации по требованиям ФСТЭК.
При проектировании такой системы необходимо уделять особое внимание безопасности, масштабируемости и полноте аудита, чтобы обеспечить надёжную поддержку правовой деятельности органов военной юстиции.