Commit Graph

9 Commits

Author SHA1 Message Date
Zimin A.N. 5d5b03c421 fix(cuod-bundle): spacecraft seed records — мигрировать статусы на новый FK
Bundle v1.2.1 ввёл x-references на spacecraft_status, но seed records
оставались со старыми enum-значениями (ACTIVE, DECAYED) которых нет
в spacecraft_status.records.json.

Migration:
- ACTIVE (12 records) → OPERATIONAL  (штатная целевая работа)
- DECAYED (2 records) → LOST  (аварийная потеря или внеплановый сход)

Mapping выбран по семантике: ACTIVE = currently working = OPERATIONAL.
DECAYED означает unplanned re-entry = LOST (DECOMMISSIONED это плановый
вывод). После следующего bundle re-import (TRUNCATE+restart) seed
будет проходить x-references validation.
2026-05-06 18:11:23 +03:00
Zimin A.N. 3dddcd1f95 feat(cuod-bundle): spacecraft.status — FK на spacecraft_status
Был inline enum [PLANNED, ACTIVE, INACTIVE, DECAYED, LOST] — но
spacecraft_status справочник существует с нормализованными codes:
PLANNED, LAUNCHED, OPERATIONAL, STANDBY, DEGRADED, DECOMMISSIONED, LOST.

Теперь spacecraft.status = x-references на spacecraft_status.code.
Profit:
- i18n названий статусов (Запланирован/Эксплуатация/...)
- description per status (что значит DEGRADED vs DECOMMISSIONED)
- Расширяемо без schema migration

Breaking change: existing 14 records со status=ACTIVE/DECAYED не пройдут
validation. Решение: full re-import bundle на staging (TRUNCATE +
restart ordinis-app → CuodBundleStartupRunner пересоздаст все).
2026-05-06 17:34:39 +03:00
Zimin A.N. 7b6e2145ea feat(cuod-bundle): v1.2.1 — x-references на 5 FK полях
Демо нового x-references validator (commit 4142678).
До этого FK relationships были только в description как "FK на ...".
Теперь app-level integrity check на CRUD:

- spacecraft.satellite_type_code → satellite_type.code
- consumer.consumer_type → consumer_type.code
- deliverable_type.typical_processing_level → processing_level.code
- orbital_regime.parent_orbit_type → orbit_type.code
- antenna.ground_station → ground_station.code

Effect: POST/PUT записи с invalid FK → 422 ValidationError code
x_references_target_not_found, не silent broken reference.

Bundle version bumped 1.2.0 → 1.2.1 (breaking-change detection
прокатит — schemaVersion полей не менялись, только metadata).
2026-05-06 17:18:28 +03:00
Zimin A.N. b57bc9ef82 feat(cuod-bundle): +33 справочника — bundle v1.2.0
Расширение каталога ЦУОД с 7 до 40 справочников. Покрывает домен ДЗЗ
end-to-end: КА → орбиты → сенсоры → данные → потребители → съёмка → гео →
обработка → связь → контракты.

КА и операторы (5):
- country (ISO 3166-1 — RU/US/CN/EU/etc, 14 записей)
- operator (Роскосмос, NASA, ESA, NOAA, Maxar, Planet, ..., 13)
- spacecraft_status (planned/launched/operational/standby/degraded/decommissioned/lost, 7)
- launch_vehicle (Союз-2/Ангара/Falcon 9/Ariane 6/Long March 2D, 12)
- launch_site (Байконур/Восточный/Cape Canaveral/Куру/Tанегасима, 9)

Орбита (3):
- orbit_type (LEO/SSO/MEO/GEO/HEO/POLAR, 6)
- orbital_regime (SSO AM/PM/dawn-dusk, Молния, Тундра, GEO standard, 6)
- inclination_class (экваториальный → ретроградный, 8)

Сенсоры (5):
- sensor_type (optical PAN/MS, hyperspectral, thermal, SAR, lidar, microwave, 8)
- spectral_band (PAN/B/G/R/RedEdge/NIR/SWIR1/SWIR2/MWIR/TIR/CoastalAerosol/H2O/Cirrus, 13)
- frequency_band (P/L/S/C/X/Ku/K/Ka/UHF, 9)
- polarization (HH/HV/VH/VV, 4)
- resolution_class (VHR/HR/MR/LR/VLR с GSD-границами, 5)

Данные (4):
- coordinate_system (WGS84/Web Mercator/ECEF/ПЗ-90.11/ГСК-2011/СК-42/СК-95/UTM, 9)
- map_projection (Меркатор/UTM/Гаусс-Крюгер/Альберс/Ламберт/Polar Stereo/Sinusoidal/Web Mercator, 8)
- compression_algorithm (NONE/LZW/Deflate/PackBits/JPEG/JPEG2000/ZSTD/LERC, 8)
- qa_flag (Cloud/Shadow/Cirrus/Snow/Water/Saturated/Missing/SunGlint/AtmCorrected/GeomRefined, 10)

Потребители (4):
- consumer (МЧС/Минприроды/Росреестр/Минсельхоз/Росгидромет/Рослесхоз/Минобороны, 7) [scope=INTERNAL]
- consumer_type (министерство/агентство/гос/коммерческая/научная/международная, 7)
- industry_sector (агро/лес/картография/ЧС/экология/метео/нефтегаз/Арктика/...,  14)
- priority_class (P0 emergency → P5 background с SLA в часах, 6)

Съёмка (2):
- imaging_task_type (плановая/заказная/экстренная/strip/stereo/background, 6)
- acquisition_mode (nadir/off-nadir/stripmap/spotlight/scansar/stereo/tristereo, 7)

Гео (3):
- coverage_zone (8 ФО + Арктическая зона, 9)
- climatic_zone (Кёппен: тропики → ледник, 9)
- land_cover_type (ESA WorldCover 11 классов, 11)

Обработка (2):
- atmospheric_correction (Sen2Cor/iCOR/MAJA/6S/MODTRAN/ACOLITE/FLAASH, 7)
- geometric_correction (RPC/RPC+GCP/Ortho-DEM/rigorous-sensor/polynomial-2D, 5)

Связь (2):
- antenna (антенны GS Москва/Ханты/Красноярск/Хабаровск, 4) — FK на ground_station
- modulation_scheme (BPSK/QPSK/8PSK/16APSK/32APSK/64QAM, 6)

Контракты (3) [scope=INTERNAL для contract_type/license_type]:
- contract_type (госзаказ/rate-card/подписка/проектный/обмен, 5)
- license_type (open/CC-BY-NC/internal/single-user/enterprise/restricted/secret, 7)
- deliverable_type (raw/L1B/L1C/L2A/NDVI/DEM/landcover/event-report, 8)

manifest.json: bundle.version → 1.2.0, добавлены все 33 dictionary descriptors
с переводами и scope.

Все JSON-файлы валидируются `python3 -c "json.load"`. Maven build success.
Bundle грузится writer'ом при старте (см. CuodBundleAutoConfiguration).
2026-05-06 00:57:48 +03:00
Zimin A.N. 2fc9b451e4 fix(cuod+docs): Resurs-P/Канопус/Метеор/Электро/Арктика в seed + правильный read-api путь
Альтум-команда обнаружила что /api/v1/dictionaries/{name}/records даёт 500
и spacecraft_codes ссылаются на несуществующий "RESURS-P-3". Оба бага мои:

1. Read-api живёт на /api/v1/{name}/records (БЕЗ /dictionaries/ префикса).
   /dictionaries/* — это admin-write контроллер, у него GET-list нет.
   Fix: docs/integration/altum-imaging-order.md + docs/tech/api-integration.md
   обновлены с правильными URL'ами + примером ответа из live staging.

2. spacecraft seed имел только 4 КА (Terra, Sentinel-1A/2A, Кондор-ФКА),
   а mission.spacecraft_codes ссылался на пустые/RESURS-P-3 — каскад в
   "Заказ съёмки" не работал бы.
   Fix: добавлено 10 российских КА (Ресурс-П 1-4, Канопус-В 1+5, Метеор-М 2+2-2,
   Электро-Л 2, Арктика-М 1) с COSPAR designators как businessKey.

3. mission.records.json + instrument.records.json: spacecraft_codes теперь
   ссылается на реально существующие COSPAR-ключи. Каскад работает:
   instrument MSU-MR → spacecraft [2014-037A, 2019-038A] → Метеор-М № 2 / 2-2.

После redeploy и идемпотентного пересева:
  spacecraft   14 (было 4, +10 РФ)
  mission       9 (existing 9, references фиксированы)
  instrument   11 (было 10, +МСУ-ГСМ Арктики)
2026-05-04 18:27:36 +03:00
Zimin A.N. e284fa85be feat(cuod): + 4 справочника mission, instrument, processing_level, data_format
Греет Альтум-интеграцию (заказ съёмки) и любых других consumer'ов ДЗЗ.
Манифест cuod 1.0.0 → 1.1.0. Existing справочники (spacecraft, satellite_type,
ground_station) не тронуты — их schemaVersion остался 1.0.0.

Схемы:
- mission: программа/семейство КА (Ресурс-П, Канопус-В, Sentinel и т.д.)
- instrument: бортовой сенсор с m2m связью со spacecraft и cascade в
  data_format/processing_level через supported_*_codes
- processing_level: L0...L4 с sort_order для упорядочивания
- data_format: GeoTIFF/NITF/COG/SAFE/... с MIME + расширением

Везде x-id-source=code (auto businessKey), x-unique=true на code.
Поля name/description везде x-localized RU+EN.

Сидинг (35 записей):
- mission: 9 (российские + Sentinel + Terra/Aqua)
- instrument: 10 (Геотон-Л1, КШМСА, ГСА-2, ПСС-В, МСУ-МР, МСУ-ГС, Кондор SAR, MODIS, C-SAR, MSI)
- processing_level: 8 (L0/L1A/L1B/L1C/L2A/L2B/L3/L4)
- data_format: 8 (GEOTIFF, COG, NITF, JPEG2000, NETCDF, HDF5, SAFE, KMZ)

Cross-refs работают: mission.spacecraft_codes и instrument.spacecraft_codes
ссылаются на existing spacecraft businessKeys; instrument.supported_*_codes —
на новые data_format/processing_level. Импортер CuodBundleImporter
идемпотентен — на ребуте поднимет всё, существующее не тронет.
2026-05-04 15:44:38 +03:00
Александр Зимин 0752b3acd6 fix(cuod-bundle): seed records for existing definitions too
Importer бросал early-return для уже существующих definitions, поэтому
records никогда не наполнялись на повторных стартах. Records seed
теперь вызывается всегда (idempotent — skip по businessKey).
2026-05-03 23:38:52 +03:00
Александр Зимин aab7199600 feat(cuod-bundle): seed records auto-import on startup
CuodBundleImporter теперь после создания DictionaryDefinition подгружает
records/<name>.records.json (relative to bundle resourceRoot) и создаёт
DictionaryRecord для каждой записи. Идемпотентно: пропускает business_key,
который уже существует.

Bundle:
- 5 satellite_type (SAR_X_HIRES, OPT_HIRES_VIS, OPT_MIDRES_MS, HYPER, METEO_GEO)
- 4 spacecraft (Terra, Sentinel-1A, Sentinel-2A, Кондор-ФКА №2)
- 3 ground_station (Отрадное, SvalSat, Байконур)

Все с локализованными name/description (ru-RU + en-US), валидируемые
JSON Schema на pre-save. Outbox events RecordCreated отправляются для
projection-writer.
2026-05-03 23:31:51 +03:00
Zimin A.N. ae69a7642b feat(cuod-bundle): JSON Schema драфты для spacecraft/satellite_type/ground_station + auto-import
3 schema драфта в classpath:/bundles/cuod/:

- spacecraft.schema.json: КА с COSPAR designator, NORAD ID, multi-locale
  name/operator/mission, orbit params (type/semimajor/eccentricity/inclination/
  raan/aop/epoch), spectrum_bands (12 bands), launch/decay dates, status enum
- satellite_type.schema.json: классификация КА — code, multi-locale name/desc,
  mission_category enum (10 categories), mass_class, typical_orbit_classes,
  typical_resolution_m, typical_revisit_hours
- ground_station.schema.json: code, multi-locale name/location/operator,
  country (ISO 3166), lat/lon/elevation, antennas array (id, diameter,
  bands, polarizations, tx/rx_capable, G/T, EIRP), status

manifest.json: bundle 'cuod' v1.0.0, 3 dictionaries с supported_locales
[ru-RU, en-US] default ru-RU, scope PUBLIC

ordinis-cuod-bundle модуль:
- BundleManifest record + DictionaryEntry record (Jackson deserializer)
- CuodBundleProperties @ConfigurationProperties (auto-import flag,
  update-existing-schema flag, resource-root path)
- CuodBundleImporter @Service (proxified, @Transactional работает) — читает
  manifest + schemas, для каждого: findByName → если нет, создать definition
  + outbox event DefinitionCreated; если есть, проверить schema_version, при
  отличии и update_existing_schema=true — обновить + DefinitionUpdated outbox
- CuodBundleStartupRunner @Configuration с ApplicationRunner — триггерит
  importBundle при старте Spring Boot. Отделено от Importer чтобы Importer
  оставался proxified (@Transactional на importBundle vs lambda не работает)

ordinis-validation FIX:
- RecordValidator теперь учитывает required array родительской схемы.
  Отсутствие x-localized optional поля (например mission, operator) больше
  не считается ошибкой. Required x-localized поля по-прежнему обязательны.

E2E проверено:
- ORDINIS_BUNDLE_CUOD_AUTO_IMPORT=true → 3 справочника создались с правильными
  scope, locales, schema_version
- POST spacecraft с реальными Kanopus-V данными (orbit + spectrum_bands) → 201
- POST satellite_type с code='lower-case-bad' → 422 pattern error
- Idempotent: повторный старт пропускает existing без ошибок
2026-05-03 14:29:43 +03:00