ShipCore-Avia — Air Cargo¶
Status: Phase 9+ (deferred). Power-pivot per C2 — від «build AWB module» до «partner with Awery + ONE Record interop». Awery — UA-походження, 5× IATA ONE Record Hackathon winner, ОДКР готує open-source PHP ONE Record reference server.
§ 1. Module Mission¶
Mission. ShipCore-Avia — це тонкий interop layer між ShipCore-Forwarder і Awery (primary partner). Не повноцінний AWB engine, а bidirectional data exchange (Booking → AWB → events back) через ONE Record (REST API + RDF/JSON-LD). Покриває air-leg як один з legs у multi-modal Booking. Outreach до Awery — Phase 4-5 calendar window, production rollout — Phase 9+.
Target клієнт.
- UA forwarder з air cargo desk — типово 200-1000 employees, AWB volume 50-500/month. Через ShipCore-Forwarder Booking з air-leg.
- Awery existing customers UA — мають Awery для air-side, додають ShipCore для ground/multi-modal/UA-compliance.
- Charter brokers — Phase 9++ (потребує CharterContract model + Awery Charter module integration).
Wedge у avia vertical. 1. Partnership over build — Awery 5× hackathon winner на IATA WCS 2026, ONE Record thought leader. Конкурувати з нуля = втрата років. Partnership = 6 місяців до production. 2. ONE Record bidirectional — обидві сторони speak ONE Record. Standards-based, не proprietary integration. Phase 8 ShipCore вже має ONE Record consumer infrastructure (через eFTI air sub-domain). 3. UA-compliance layer для Awery — через ShipCore-Forwarder UA forwarder отримує eTTN/M.E.Doc/Дія КЕП для ground-leg + Awery для air-leg = повний complete UA-compliant TMS. 4. Awery PHP open-source ONE Record server (P2-N10) — можемо переюзати їхню schema/models як foundation, не з нуля.
§ 2. Поточна реалізація (статус quo)¶
2.1 Що НЕ існує¶
ShipCore-Avia не існує як backend app. Жодних моделей, ViewSets, frontend компонентів.
2.2 Recon з Phase 0/1/2¶
- D2: paid plugin за конвенцією (як sea/rail/terminal/forwarder).
- D6: окрема Django app
backend/shipcore_avia/(stub з мінімальним кодом до Phase 9+). - C2: Awery partnership як основа scope, не build own AWB engine.
- P2-N10: Awery OSS PHP ONE Record server — переюзаємо їхню foundation для adapter, не з нуля.
- Phase 1 standards-matrix § 1.3: mandatory transition Cargo-IMP/Cargo-XML → ONE Record з 2026-01-01. Awery вже leader.
§ 3. Цільовий стан v2 (Phase 9+)¶
Архітектурний підхід: thin layer над Awery. Моделі ShipCore-Avia — мінімальні, лише для зв'язку Booking ↔ Awery AWB. Реальні AWB/ULD/charter — у Awery.
3.1 Моделі (мінімальні stubs)¶
# backend/shipcore_avia/models/awb_link.py
class AWBLink(TenantScopedModel):
"""Тонкий зв'язок Booking ↔ Awery AWB.
Реальна AWB live у Awery — ми зберігаємо лише посилання + cached snapshot."""
booking_leg = OneToOne('shipcore_forwarder.BookingLeg', related_name='awb_link')
awb_number = CharField(max_length=15, db_index=True)
# IATA AWB format: prefix(3) + serial(8) + check digit
# Example: '297-12345678'
awb_type = CharField(choices=[
('master', 'Master AWB (MAWB)'),
('house', 'House AWB (HAWB)'),
])
parent_master = FK('self', blank=True, null=True, related_name='houses')
awery_one_record_uri = URLField(blank=True)
# ONE Record canonical URI from Awery: <iata-one-record>/logistics-objects/<uuid>
awery_internal_id = CharField(max_length=80, blank=True)
# Awery's own ID (for back-pointer support)
last_synced_at = DateTimeField(blank=True, null=True)
cached_payload = JSONField(default=dict)
# Cached ONE Record JSON-LD snapshot for offline reads
status = CharField(max_length=40, blank=True)
# FSU status: FOH (Freight On Hand), RCS (Received from Shipper),
# DEP (Departure), ARR (Arrival), RCF (Received from Flight), DLV (Delivered)
# backend/shipcore_avia/models/airline.py
class Airline(TenantScopedModel):
"""Master data — IATA airlines що ми бачимо у Awery feed.
Auto-populated через Awery sync — ShipCore не редагує."""
iata_code = CharField(max_length=2, unique=True, db_index=True)
# 'LH', 'KL', 'LO', 'MS', 'TK', 'AY', ...
icao_code = CharField(max_length=3, unique=True)
# 'DLH', 'KLM', 'LOT', 'MSR', 'THY', 'FIN', ...
name = CharField(max_length=120)
country = CharField(max_length=2)
awb_prefix = CharField(max_length=3) # 020 for LH, 074 for KL, ...
is_one_record_compliant = BooleanField(default=False)
# backend/shipcore_avia/models/airport.py
class Airport(TenantScopedModel):
"""IATA + ICAO codes."""
iata_code = CharField(max_length=3, unique=True, db_index=True)
# KBP, FRA, AMS, ...
icao_code = CharField(max_length=4)
# UKBB, EDDF, EHAM, ...
name = CharField(max_length=120)
city = CharField(max_length=80)
country = CharField(max_length=2)
timezone = CharField(max_length=40)
is_cargo_hub = BooleanField(default=False)
3.2 Awery integration adapter¶
# backend/shipcore_avia/integrations/awery/adapter.py
class AweryAdapter:
"""Bidirectional adapter via ONE Record + Awery REST API.
Authentication:
- OAuth2 (assumed (?), partner-gated docs)
- API key as fallback for read-only
Data exchange model (Model C per phase2-tracking-partnerships):
ShipCore Booking → ONE Record payload → Awery
Awery AWB events → ONE Record payload → ShipCore ShipmentEvent
"""
BASE_URL = "https://api.awery.com" # placeholder, partner-gated
ONE_RECORD_BASE = "https://one-record.awery.com/api/v1"
async def push_booking(self, booking: Booking) -> str:
"""
1. Build ONE Record LogisticsObject (Shipment + Pieces + Parties)
2. POST {ONE_RECORD_BASE}/logistics-objects → Awery URI
3. Awery internally creates AWB record + assigns AWB number
4. Returns AWB number + ONE Record URI
"""
async def pull_awb_events(self, awb_number: str) -> list[ShipmentEvent]:
"""
1. GET {ONE_RECORD_BASE}/logistics-objects/{awb_uri}/events
2. Parse FSU events: FOH/RCS/DEP/ARR/RCF/DLV
3. Map до ShipCore ShipmentEvent (UNECE-compatible event_code)
"""
async def get_quote(self, origin: Airport, destination: Airport,
weight_kg: Decimal, departure_window: tuple) -> list[QuoteOption]:
"""
Awery's air rate quote API. Returns options across multiple airlines.
"""
async def stream_events(self, since: datetime | None = None):
"""
Webhook subscription OR polling fallback.
Yields ShipmentEvent records.
"""
3.3 Services¶
# backend/shipcore_avia/services/booking_air_leg.py
async def add_air_leg_to_booking(
booking: Booking,
origin_airport: Airport,
destination_airport: Airport,
cargo_weight_kg: Decimal,
pickup_date: date,
) -> BookingLeg:
"""
1. Create BookingLeg(mode='air')
2. Call AweryAdapter.get_quote() → options
3. User selects option (UI step)
4. AweryAdapter.push_booking() → AWB number + ONE Record URI
5. Create AWBLink linking BookingLeg ↔ Awery AWB
6. Subscribe to Awery webhook for AWB events
"""
async def sync_awb_status(awb_link: AWBLink) -> int:
"""
Periodic poll fallback (якщо webhook lost).
Returns count of new events synced.
"""
3.4 ViewSets / API endpoints¶
| URL | Method | Operation |
|---|---|---|
/api/avia/awb-links/ |
GET | List AWB links per booking |
/api/avia/awb-links/{id}/ |
GET | Detail з cached payload |
/api/avia/awb-links/{id}/sync/ |
POST | Manual trigger sync from Awery |
/api/avia/airlines/ |
GET | Read-only Airline master data |
/api/avia/airports/ |
GET | Read-only Airport master data |
/api/avia/quote/ |
POST | Pull air-leg quote через Awery |
/api/webhooks/awery/ |
POST | Awery webhook listener |
3.5 Frontend компоненти (Phase 9+)¶
frontend/erp/src/components/ShipCore/Avia/— нова root, мінімальний обсягAirLegPanel.tsx— embedded у BookingForm: air-leg quote/select/trackAwbStatusTimeline.tsx— FSU events timeline (FOH→RCS→DEP→ARR→RCF→DLV)AweryConnectionStatus.tsx— health monitoring у Settings
3.6 Integrations¶
| Integration | Status | Phase | Notes |
|---|---|---|---|
| Awery API + ONE Record interop | 📋 NEW | 9+ | Primary, post-partnership |
| WIN platform (e-AWB connectivity) | 📋 NEW | 9+ | Як partner до Awery, не rate aggregator (per P2-R1) |
| IATA Cargo-XML | 📋 deferred | — | Sunset 2026-01-01 (containment) — skip |
| IATA Cargo-IMP | 📋 deferred | — | Legacy, skip |
| IATA ONE Record direct (without Awery) | 📋 deferred | 10+ | Optional fallback if Awery partnership fails |
§ 4. Phase plan¶
Phase 4-5 — Outreach window (per C2)¶
Action items (parallel з основним impl track):
1. LinkedIn outreach — Tristan Koch (CCO/CXO Awery) primary; Vladimir Gabovich (COO) escalation
2. IATA WCS 2027 (March) — face-to-face during keynote/booth
3. Direct email через partners@awery.aero (?) — secondary після LinkedIn warm-up
4. Через UA tech community — Awery R&D з Києва, intro через Lviv/Kyiv tech meetups
Deliverable: - Introductory call + share ShipCore concept doc (1-page, non-NDA) - Goal: signed exploratory MoU, not commitment
Phase 6-7 — Design phase (if Awery positive)¶
Action items: 1. Design ONE Record interop spec разом з Awery 2. ShipCore робить proof-of-concept Booking → AWB exchange 3. Validate з 1-2 forwarder pilot tenants що мають air desk
Deliverable: - ONE Record interop spec document - PoC working на test environment
Phase 9+ — Production rollout (Model C bidirectional)¶
Scope:
- [ ] backend/shipcore_avia/ Django app skeleton
- [ ] AWBLink, Airline, Airport models
- [ ] AweryAdapter implementation (push_booking + pull_awb_events + stream_events)
- [ ] ONE Record JSON-LD payload builder/parser (using Awery OSS PHP ONE Record server foundation per P2-N10)
- [ ] Frontend: AirLegPanel + AwbStatusTimeline + AweryConnectionStatus
- [ ] Tests: ≥15 (booking push, event sync, ONE Record payload validation)
- [ ] Documentation: integration playbook для customer onboarding
Dependencies: - Awery commercial agreement signed (Model C technical interop, no reseller relationship) - ShipCore-Forwarder Booking workflow stable (Phase 5+) - ONE Record consumer infrastructure ready (Phase 8 — eFTI air sub-domain)
Estimate: ~4-6 тижнів post-partnership (60-80h Awery integration + 20-30h ONE Record interop)
Phase 9++ — Optional advancements¶
- Charter ops (CharterContract model + Awery Charter module integration)
- ePOUCH (Lufthansa Cargo) connector
- e-AWB через WIN platform (IATA Cargo XML / Cargo-IMP fallback) — для airlines не на ONE Record
§ 5. Compliance integration¶
5.1 Документи¶
| Документ | Стандарт | Phase | Trigger |
|---|---|---|---|
| AWB (paper) | IATA Resolution 600a | 9+ | Via Awery |
| eAWB / ONE Record | IATA ONE Record (preferred з 2026-01-01) | 9+ | Via Awery — primary |
| Cargo-XML | IATA Cargo-XML (sunset 2026-01-01 containment) | — | Skip — Awery handles legacy |
| eFTI air | Reg (EU) 2020/1056 (air sub-domain) | 9+ | Via ONE Record reuse |
| ICS2 ENS Air | Reg (EU) 2015/2447 (R1+R2 для air) | 9+ | Pre-arrival cross-border to EU |
| DGR (Dangerous Goods) | IATA DGR Manual | 9+ | When cargo hazardous |
5.2 Інтеграція з backend/shipcore/compliance/¶
backend/shipcore/compliance/
├── exporters/
│ └── efti_air.py ← schema-agnostic, reuses Awery PHP ONE Record OSS (per P2-N10)
└── integrations/
└── ics2_air.py ← R1+R2 air ENS through ITSP partner (Phase 9+)
5.3 ONE Record bidirectional model (Model C)¶
Per phase2-tracking-partnerships § 2.4:
ShipCore-Forwarder.Booking (multi-modal)
│
├─── road leg → ShipCore-Auto.Waybill (eTTN/eCMR)
├─── sea leg → ShipCore-Sea.OceanBooking (DCSA)
├─── rail leg → ShipCore-Rail.RailwayWaybill (СМГС/CIM)
└─── air leg → ShipCore-Avia.AWBLink ──► Awery AWB
│
ONE Record JSON-LD bidirectional sync
Key benefits: - Standards-based — ONE Record specification public (IATA standard) - No commercial agreement needed for technical interop - Each side maintains domain expertise: Awery = aviation; ShipCore = UA compliance + multi-modal
§ 6. Standards mapping¶
| Стандарт | Куди в моделі |
|---|---|
| AWB number | AWBLink.awb_number (15-char: prefix-serial) |
| IATA 2-letter | Airline.iata_code |
| IATA 3-letter | Airport.iata_code |
| ICAO 3-letter | Airline.icao_code |
| ICAO 4-letter | Airport.icao_code |
| AWB prefix | Airline.awb_prefix (3-digit) |
| ONE Record URI | AWBLink.awery_one_record_uri (canonical RDF resource) |
| FSU events | AWBLink.status (FOH, RCS, DEP, ARR, RCF, DLV) |
| UNECE Recommendation N.24 air-events mapping | ShipmentEvent.event_code (mapped from FSU) |
| HS Code (WCO) | через Booking.hs_code |
| DGR class | через Booking cargo metadata |
| ULD codes | NOT in ShipCore models (Awery owns ULD logic) |
§ 7. Integrations specifics¶
7.1 Awery (Phase 9+ partner)¶
Per phase2-tracking-partnerships § Track 2:
| Параметр | Значення |
|---|---|
| Заснована | 2010 (UA-походження) |
| HQ | RAK (Ras al Khaimah, UAE) |
| Розмір | ~67 employees |
| CEO/Founder | Vitaly Smilianets |
| COO | Vladimir Gabovich |
| CCO/CXO | Tristan Koch (primary outreach contact) |
| Notable customers | Etihad Cargo, Network Aviation Group, Group Concorde |
| Achievements | 5× IATA ONE Record Hackathon winner; 1st digital provider integrated з IATA CO2 Connect (March 2026) |
Partnership model selected: Model C (Bidirectional ONE Record exchange).
Why Model C over A/B/D: - A (Reseller): ShipCore залежить від Awery roadmap; немає differentiation - B (White-label): Awery значно більший, переговорна позиція слабка - C (Bidirectional): clean separation of concerns. Standards-based. HIGH fit. - D (JV): занадто складно для current sizes
API documentation: partner-gated. Public developer.awery.aero portal — не виявлено на момент перевірки. Access через partnership / customer relationship.
Open-source PHP ONE Record server (per P2-N10): Awery готує OSS reference server. ShipCore може переюзати їхні schema models, не з нуля.
7.2 WIN platform (Phase 9+ optional, як partner до Awery)¶
Per phase2-tracking-partnerships § Track 3:
WIN — air-cargo connectivity hub (e-AWB до 160+ airlines), НЕ universal rate aggregator. Riege Scope використовує лише для air-leg.
ShipCore strategy:
- Phase 9+ — як partner до Awery для airlines що не на ONE Record (Cargo-XML / Cargo-IMP fallback)
- Phase 7 — НЕ used as rate aggregator (per P2-R1)
- Pricing: $200-800/міс/office estimated (no public)
- Action: outreach service@winwebconnect.com Phase 9+
7.3 ONE Record direct (Phase 10+ optional fallback)¶
Якщо Awery partnership fails OR ShipCore захоче власну незалежність: - IATA ONE Record specification public (github.com/IATA-Cargo/ONE-Record) - ShipCore може implement own ONE Record server (Python instead of Awery PHP) - Cost: 4-6 months effort to feature parity з Awery foundation - Not recommended unless partnership explicitly fails
§ 8. Open questions / Phase 3 spike-days¶
- Awery actual response до partnership outreach — критичний blocker для Phase 9+ scope. Action: Phase 4-5 — soft intro Tristan Koch via LinkedIn + share concept doc.
- Awery commercial partnership terms — outreach під час Phase 4-5 calendar window per C2 (negotiation typically 3-6 months).
- ONE Record adoption повільніша за маркетинг — IATA survey Dec 2025 «growing awareness» = diplomatic для slow. Action: Phase 8-9 — моніторинг IATA adoption metrics.
- UA-roots Awery — palpable conflict? Якщо Awery планує own UA-launch через Київ R&D — конкуренція не партнерство. Action: Phase 4-5 — перші розмови саме для калібрування цього сигналу.
- Awery API documentation gating model — public dev portal absent. Action: Phase 9+ — після MoU signed, отримати NDA + access.
- WIN actual subscription pricing — не на сайті. Action: Phase 9+ — outreach call.
- ICS2 R1+R2 для air ENS — який ITSP (Descartes / AEB) працює з air domain. Action: Phase 9+ — vendor selection після Awery integration ready.
§ 9. Linkbacks¶
- README — програмний overview ShipCore
- decisions-2026-05-12 § C2 — Awery partnership decision
- phase2-summary § P2-N10 — Awery OSS reuse
- phase2-summary § P2-R1 — WIN platform clarification
- phase2-tracking-partnerships § Track 2 — Awery partnership plan
- phase2-tracking-partnerships § Track 3 — WIN platform deep
- phase2-eu-compliance § 1.7 — eFTI air sub-domain
- phase2-carrier-apis § 6.10 — Phase 9+ Awery sequencing
- standards-matrix § 1.3 — IATA standards inventory
- integration-matrix — high-level integrations list
- roadmap — timeline (Phase 9+)
- forwarder — multi-modal Booking orchestrator (air-leg through ShipCore-Avia)
Phase 3 implementation-ready spec — 2026-05-12. Phase 9+ deferred to post-Awery partnership conversation.