Запись каталога: подписка кооператива на пакет.
Идентификация подписки — composite (coopname, package_id, chain_id):
coopname — кто подписан (Antelope name).
package_id — на какой пакет.
chain_id — в какой подсети действует подписка. Контракт apps деплоится на корневой координационной KE-цепи и обслуживает несколько подсетей; chain_id привязывает подписку к конкретной подсети, в которой кооператив находится.
plan — имя плана (basic, premium, ...). Это только метка: биллинг (расчёт стоимости, приём оплаты, выставление счёта) — задача кабинета ВОСХОД и контракта pay.coopenomics. Сюда приходит уже факт «подписка активна с X по Y по плану Z».
regsub идемпотентно по (coopname, package_id): повторный вызов с тем же ключом продлевает end_at (= max(текущее, новое)) и обновляет plan/active. Это поведение сознательное — биллинг при retry не должен бояться дубликатов.
expsub НЕ удаляет row, а ставит active=false. Запись остаётся для аудита истечения подписки. Cleanup просроченных записей — задача отдельного периодического действия (вне MVP).
Indexing:
- PK
id — auto-inc.
bycooppkg — composite (coopname, package_id) для idempotent upsert и проверки «есть ли активная подписка коопа X на пакет Y».
bycoop — все подписки одного кооператива.
byexpires — sorted by end_at для будущего auto-cleanup.
- См. также
- lib/domain/table_apps_coops.hpp — chain_id ↔ кооператив.