Files
2018-lpon-site/_prj_blueprint/_planstep_for_cassettes.md
T

13 KiB
Raw Blame History

План реализации кассетного каталога, серий и DSL-витрины

Дата и время создания/обновления: 2026-10-11 17:30
Проект: LPON.RU (Django 6.0+, Python 3.12) Статус: Согласованный рабочий план
Архитектурная спецификация метаданных: metadata_architecture.md


Архитектурные принципы и ключевые решения

1. Серии, коллекции и раритетные записи

  • Концепция: Для тематических архивов (например, радиопередачи Oobu Joobu, японские бутлеги, циклы фолк-концертов) создается обзорная статья TbArticle (тип HUB или COLLECTION).
  • Контент: Предыстория архива, контекст записей, аппаратура оцифровки/записи, сканы оригинальных вкладышей.
  • DSL-витрина серии: Внутрь статьи встраивается DSL-блок, динамически выбирающий кассеты этой серии по тегу или источнику (например, ["offers:series:oobu-joobu", "grid"]).
  • Покупка: Поддерживается покупка отдельных выпусков/кассет поштучно, а также покупка всего сета через сборный оффер-комплект.

2. Двухуровневая медиатека фотографий

  • Уровень 1 — Эталонные фото модели (TbItem / связанная TbArticle):
    • Фотографируются один раз на модель: цвет и фактура ленты (Fe, CrO2, Metal), металлизированный ракорд, люминесцентное свечение (TDK BEAM), керамические блоки, сканы каталогов тех лет.
    • Автоматически подтягиваются во все офферы данной модели кассеты.
  • Уровень 2 — Фото конкретного лота (TbOffer через TbImageMetadata):
    • 2-3 честных фото продаваемого экземпляра: реальные потертости корпуса, состояние надписей на вкладыше, целостность язычков защиты от записи.
  • Отображение в карточке: В основном блоке показывается конкретный продаваемый экземпляр, ниже выводится блок «Детали и макросъемка модели».

3. Музейный каталог (по типу c-90.org / ez647.sk) и архивные лоты

  • Сохранение проданных позиций: Офферы со статусом quantity = 0 не удаляются и не закрываются ошибкой 404. Они получают статус «Архивный лот / Продано», оставаясь доступными для SEO, просмотра истории и изучения записей.
  • Матричная структура справочника (без жесткого дерева папок):
    • Ось брендов: /cassettes/brands/ (TDK, Maxell, Sony, BASF, AXIA, Denon);
    • Хронологические линейки: разбивка внутри бренда по модельным годам (например, модельный ряд TDK 1985, 1988, 1990 годов с группировкой по типам ленты Normal / High / Metal);
    • Ось хронологии: /cassettes/timeline/ (разбивка по эпохам: 70-е, 80-е, 90-е, 2000-е).

Ближний горизонт (Пошаговый план разработки)

Шаг 1. Стандартизация схемы метаданных для кассет и всех форматов

  • Спецификация полностью зафиксирована в _prj_blueprint/metadata_architecture.md.
  • Модуль констант lpon_site/lpon_site/constants.py создан и подключен:
    • Единый реестр перечислений: MediaType, Market, TapeType, MediaLength, ShellColor, WriteProtectTabs, InlayCondition, Packaging, OfferExtra, Condition, Format.
    • Режим дефолтных шаблонов с подсказками через | (Inline Choice Placeholder) для защиты от ленивого заполнения.
  • Структура полей j_item_metadata (для TbItem):
    • media_type: blank_media, music_album, audio_recording, equipment;
    • tape_type: type_1, type_2, type_3, type_4;
    • length: 46, 50, 54, 60, 74, 80, 90, 100, 110, 120;
    • release_year: год или диапазон годов выпуска;
    • market: jp, us, eu, uk, su, global;
    • gallery_model: список ID эталонных фото модели в django-filer.
  • Структура полей j_offer_metadata (для TbOffer):
    • packaging: sealed, opened;
    • is_recorded: флаг наличия уникальной аудиозаписи;
    • recording_info: краткое резюме записи (или ссылка на отдельную статью k_offer_to_article);
    • write_protect_tabs: intact, broken;
    • inlay_condition: clean, pencil, written, missing;
    • series_tag: слаг серии/коллекции (при наличии);
    • extras: словарь опций комплектации (obi, insert, poster, case_original, stickers_sheet и др.).

Шаг 2. Ядро DSL и реестр обработчиков (DSLQueryRegistry)

  • Создать модуль реестра обработчиков (Query Handlers), разбирающий кортежи формата: ["source", "view_mode", limit, "sort", extra]
  • Реализовать базовые обработчики источников:
    • Одиночные сущности по слагу (single_slug);
    • Выборки статей (articles:type:<type>, articles:collection:<slug>);
    • Выборки офферов (offers:format:cassette, offers:label:<slug>, offers:tape_type:<type>, offers:series:<tag>);
  • Реализовать сортировки:
    • new+, new-, price+, price-, year+, year-, view+, random;
  • Поддержка составных режимов и лимитов (view_mode = "teaser+list", limit = "2+15").
  • Защита от зацикливания (visited_slugs, MAX_RECURSION_DEPTH = 2) и безопасная деградация при ошибках в JSON.

Шаг 3. Шаблоны компонентов и кастомный Template Tag

  • Реализовать template tag {% render_hub_blocks article %} (или фильтр рендеринга хабов).
  • Разработать базовую карточку кассеты (cassette_card.html):
    • Фото экземпляра, бейджи типа ленты, хронометража и года, плашка состояния («Под перезапись» или «Запись: Название»), цена/статус наличия.
  • Разработать шаблоны раскладки для разных view_mode:
    • grid.html (адаптивная сетка карточек);
    • carousel.html (горизонтальная прокрутка);
    • list.html (компактный табличный список);
    • timeline.html (раскладка по годам и линейкам для музейного каталога);
    • teaser.html (промо-блок статьи/серии).

Шаг 4. Шаблоны страниц и виртуальные хабы

  • Шаблон детальной страницы товара/кассеты:
    • Основная галерея фото конкретного лота + ТТХ и состояние;
    • Блок «Детали и макросъемка модели» (эталонные фото из TbItem);
    • Блок описания аудиозаписи с треклистом (если привязана статья к офферу);
    • Автоматический виртуальный DSL-блок («Другие кассеты этого бренда», «Другие кассеты Type II»).
  • Шаблон страницы серии/коллекции:
    • Вводная статья + встроенная DSL-сетка кассет серии + блок заказа всей подборки.
  • Подключение рендеринга блоков в content/hub.html и content/article_detail.html.

Шаг 5. Пилотная партия и тестирование витрины

  • Внести в базу 10-15 реальных кассет разных брендов и категорий:
    • 3 чистые кассеты Type I (TDK D, Sony HF);
    • 3 кассеты Type II (Maxell XL-II, TDK SA);
    • 1 топовая кассета Type IV (Metal) или спец-серия со светящимся корпусом (TDK BEAM);
    • 1 мини-серия из 3-4 кассет с редкими записями (Oobu Joobu / британский фолк) с оформленной статьей-хабом.
  • Собрать главный хаб кассетного раздела /cassettes/.
  • Проверить визуальное отображение, фильтрацию и мобильную верстку.

Среднесрочный горизонт

6. Бесконтактная корзина и анонимные заказы (Stateless Orders)

  • Клиентский модуль !cart-app (хранение кодов офферов s_offer_code в LocalStorage/Cookies).
  • Интеграция виджета доставки (СДЭК) и генерация анонимных трек-номеров без сбора ПДн в БД сайта (152-ФЗ compliance).

7. История слагов и SEO-редиректы

  • Модель TbArticleAlias для автоматического сохранения старых слагов при переименовании статей и отдачи 301 Permanent Redirect.

Дальний горизонт

8. Парсеры и фоновые очереди

  • Интеграция Celery / Redis воркеров для разбора внешних источников данных.
  • Реализация интерфейса ValidatorQueue в админке для разрешения коллизий синонимов и дубликатов перед записью в основную базу.

[ TbArtist ] ──(M2M)──► [ TbItem ] ──────► [ TbOffer ]
(Донован)               (Релиз / Модель)     (Конкретный лот на складе)
                            │                      │
                            ▼                      ▼
                       [ TbArticle ]          [ TbArticle ]
                     (Эталонная статья)    (История записи / лота)
Сущность Что представляет Источник наполнения Связь с артистом
Винил (LP) Музыкальный альбом на виниле Парсер Discogs / MusicBrainz Да (TbItem.k_item_to_artist)
Компакт-диск (CD) Музыкальный альбом на CD Парсер Discogs / MusicBrainz Да (TbItem.k_item_to_artist)
Кассета с записью / Бутлег Редкий концерт / оцифровка / альбом Ручной ввод / CSV Да (TbItem.k_item_to_artist)
Чистая кассета / MD под запись Модель носителя (TDK, Maxell, Sony) Музейный каталог кассет Нет (привязана к TbLabel бренда)
Серия / Архив (Oobu Joobu) Коллекция связанных кассет Статья-хаб TbArticle Да (через тег серии и артиста)

Технический долг и текущие замечания по коду

  1. Импорты во frontend/views.py: Заменить from lpon_site.settings import * на from django.conf import settings и удалить неиспользуемый import json.
  2. Временные вьюхи: Заменить временные статические функции catalog() и info_articles_list() на единый диспетчер хабов по мере готовности DSL.
  3. Заглушка get_hub_context: Реализовать полноценный вызов DSLQueryRegistry вместо отдачи сырого JSON.