[drive-download] README 070326.docx
Сущности
Вот полный README для нового чата и репозитория. Включает всё — архитектуру, файлы, настройки, эндпоинты, CSS-дизайн-систему, известные проблемы и процедуры деплоя.<br>
🇰🇿 Моя Конституция (constitution.my)<br>
Информационный сервис FAQ/разъяснений о Конституции Казахстана.<br>
Stack: FastAPI + PostgreSQL + Nginx + Docker Compose.<br>
VPS: srv1380923 → /opt/constitution/app<br>
Домен: constitution.my (IP: 62.72.32.112, порт 8080)<br>
Файловая структура<br>
text<br>
/opt/constitution/app/<br>
├── docker-compose.yml # 3 контейнера: api, db, nginx<br>
├── .env # DB credentials (НЕ в Git!)<br>
├── api/<br>
│ └── main.py # FastAPI backend (Uvicorn)<br>
├── static/<br>
│ ├── style.css # Единый CSS (~1200 строк)<br>
│ ├── index.html # Главная (featured feed)<br>
│ ├── search.html # Страница поиска (client-side)<br>
│ ├── basics.html # Раздел "База"<br>
│ ├── glossary.html # Глоссарий (аккордеон)<br>
│ └── timeline.html # Таймлайн (интерактив)<br>
├── templates/<br>
│ └── item.html # Jinja2 SSR-шаблон карточки FAQ<br>
├── import_yaml.py # Импорт content.yaml → PostgreSQL<br>
├── content.yaml # Контент (вопросы/ответы, 3 языка)<br>
├── nginx.conf # Nginx reverse proxy config<br>
├── deploy.sh # Скрипт деплоя с health-check<br>
├── backup.sh # Бэкап БД с ротацией<br>
└── faq_app_view.sql # SQL view для приложения<br>
Docker Compose<br>
3 контейнера:<br>
API Endpoints<br>
База данных<br>
Schema: app<br>
Ключевые таблицы:<br>
app.faq_sections — разделы (code, title)<br>
app.faq_items — вопросы (canonical_slug, section_id, sort_order, is_featured)<br>
app.faq_i18n — локализации (item_id, lang, question, short_answer, answer_html, facts_html, what_not_change_html, where_detailed_html, misconceptions_html)<br>
Section codes: basics, referendum, changes, timeline, rights, institutions, implementation, myths<br>
Языки: ru, kk, en (fallback → ru)<br>
FTS конфигурации: ru → russian, kk → simple, en → english<br>
CSS Дизайн-система (static/style.css)<br>
CSS Variables<br>
css<br>
--bg: #f4f6fa; --card: #ffffff;<br>
--text: #0f172a; --muted: #64748b;<br>
--line: #e8ecf1; --accent: #2563eb;<br>
--accent-bg: rgba(37,99,235,.06);<br>
--warn: #f59e0b; --radius: 14px;<br>
--font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;<br>
Ключевые компоненты<br>
.wrap — контейнер max-width: 820px, центрирован<br>
.topbar-unified — sticky навбар (logo + nav-inline + lang-sw)<br>
.card — карточка с border-radius: 14px, тенью, hover-анимацией<br>
.myths-card — карточка мифов (border-left: warn, gradient bg)<br>
.hero — блок hero на accent-bg<br>
.item-layout — 2-column grid для страницы карточки (content + sidebar 180px)<br>
.foot — footer (pills навигация, соцсети, копирайт)<br>
Footer (.foot)<br>
css<br>
.foot { margin-top: 40px; padding: 24px 0 20px; background: var(--bg); border-top: 1px solid var(--line); }<br>
.foot-inner { max-width: 820px; margin: 0 auto; padding: 0 16px; }<br>
.foot-nav a { padding: 5px 12px; border-radius: 999px; background: #eef0f4; font-size: 12px; font-weight: 600; }<br>
.foot-social a { width: 34px; height: 34px; border-radius: 10px; background: #eef0f4; }<br>
⚠️ КРИТИЧНО: HTML-структура footer<br>
.foot ДОЛЖЕН быть ВНЕ .wrap! Иначе стили не применяются (border-top, full-width background пропадают).<br>
xml<br>
<div class="wrap"><br>
<!-- content --><br>
</div> <!-- ← wrap закрывается ЗДЕСЬ --><br>
<div class="foot"><br>
<div class="foot-inner">...</div><br>
</div><br>
Это уже исправлено в search.html и item.html, но при создании новых страниц — проверять!<br>
Item page стили<br>
.item-layout — white card с border-radius: 12px, padding: 28px 32px<br>
.breadcrumb — 12px, color #aaa<br>
.item-content h1 — 22px, 800 weight<br>
.item-content .lead — 14px, italic removed, color #888<br>
.toc-box — sticky sidebar TOC (top: 24px)<br>
.side-share — share icons (copy, telegram, whatsapp)<br>
.md h2 — 16px, 700 weight, color #1a1a1a (без border-left)<br>
.md table — bordered, border: 1px solid #e5e7eb, th background #f7f8fa<br>
Mobile (max-width: 768px)<br>
Topbar: 2 rows (brand+lang / nav pills)<br>
Item layout: single column, sidebar hidden<br>
.wrap { padding: 0 !important; }<br>
Footer: column layout, smaller fonts<br>
Статические страницы<br>
Главная (/ → static/index.html)<br>
Fetch /api/featured?lang=...<br>
Grid карточек по секциям<br>
Filter bar для секций<br>
Hero блок<br>
Поиск (/search → static/search.html)<br>
Client-side: fetch /api/all?lang=..., фильтрация в JS<br>
Debounced input (200ms)<br>
Highlight <mark> для совпадений<br>
Группировка результатов по секциям с emoji: {basics:'📖', referendum:'🗳️', changes:'✏️', timeline:'📅', rights:'⚖️', institutions:'🏛️', implementation:'🔧', myths:'🔥'}<br>
Карточка (/p/{slug} → templates/item.html)<br>
SSR через Jinja2<br>
Блоки: answer_html, facts_html, what_not_change_html, where_detailed_html, misconceptions_html<br>
Sidebar: TOC (scroll-spy) + share icons<br>
OG meta tags для шэринга<br>
Деплой<br>
bash<br>
cd /opt/constitution/app<br>
git pull --rebase<br>
docker-compose up -d --build<br>
# Ждём health<br>
for i in $(seq 1 30); do<br>
curl -sf http://127.0.0.1:8080/health && break<br>
sleep 2<br>
done<br>
Проверки после деплоя<br>
bash<br>
curl http://127.0.0.1:8080/health<br>
curl -sS "http://127.0.0.1:8080/api/featured?lang=ru" | jq '.items | length'<br>
curl -sS "http://127.0.0.1:8080/api/search?q=референдум&lang=ru" | jq '.items | length'<br>
curl -sI "http://127.0.0.1:8080/p/what-changes-for-citizens?lang=ru"<br>
curl -sI "http://127.0.0.1:8080/sitemap.xml"<br>
curl -sI "http://127.0.0.1:8080/share/what-changes-for-citizens.png?lang=ru"<br>
Импорт контента<br>
bash<br>
docker exec -i constitution_db psql -U constitution -d constitution < faq_app_view.sql<br>
python3 import_yaml.py # Reads content.yaml, upserts into DB<br>
Известные проблемы / TODO<br>
Footer стили — .foot должен быть вне .wrap. Исправлено в search.html и item.html. При добавлении новых HTML — проверять структуру.<br>
Cache busting — CSS подключается с ?v=timestamp. При обновлении стилей обновлять timestamp: sed -i "s/style\.css?v=[0-9]*/style.css?v=$(date +%s)/" static/*.html templates/*.html<br>
CSS размер — ~1200 строк с множеством !important overrides. Накопленный технический долг от итеративной разработки.<br>
.env — содержит DB credentials, НЕ должен попадать в Git.<br>
Языки<br>
Fallback: если нет перевода — показывается ru.<br>
© 2025–2026 CCS LAB<br>
Этот README содержит всю информацию для продолжения работы в новом чате:[ppl-ai-file-upload.s3.amazonaws]<br>
Полная файловая структура<br>
Все API endpoints<br>
Схема БД<br>
CSS дизайн-система с переменными и компонентами<br>
Критичное правило про footer вне .wrap<br>
Mobile breakpoints<br>
Процедуры деплоя и импорта<br>
Известные проблемы<br>
<br>
Контейнер | Образ | Порт | Роль<br>
constitution_api | python:3.11 + FastAPI | 8000 (internal) | Backend API + SSR<br>
constitution_db | postgres:15 | 5432 (internal) | PostgreSQL<br>
constitution_nginx | nginx:alpine | 8080 → 80 | Reverse proxy + static<br>
Метод | Путь | Описание<br>
GET | /health | Health-check<br>
GET | / | → /static/index.html<br>
GET | /search | → /static/search.html<br>
GET | /api/item/{slug} | JSON карточки FAQ<br>
GET | /api/featured?lang=ru | Рекомендуемые вопросы<br>
GET | /api/search?q=...&lang=ru&limit=20 | Полнотекстовый поиск<br>
GET | /api/all?lang=ru | Все записи (для client-side search)<br>
GET | /p/{slug}?lang=ru | SSR-страница (SEO/OG)<br>
GET | /sitemap.xml | Динамический sitemap<br>
GET | /share/{slug}.png?lang=ru | OG-изображение<br>
GET | /robots.txt | Robots<br>
Код | Название | FTS Config | Статус<br>
Код | Название | FTS Config | Статус<br>
ru | Русский | russian | Полный<br>
kk | Қазақша | simple | Частичный<br>
en | English | english | Частичный