Перейти до змісту

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/track
  • AwbStatusTimeline.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

  1. Awery actual response до partnership outreach — критичний blocker для Phase 9+ scope. Action: Phase 4-5 — soft intro Tristan Koch via LinkedIn + share concept doc.
  2. Awery commercial partnership terms — outreach під час Phase 4-5 calendar window per C2 (negotiation typically 3-6 months).
  3. ONE Record adoption повільніша за маркетинг — IATA survey Dec 2025 «growing awareness» = diplomatic для slow. Action: Phase 8-9 — моніторинг IATA adoption metrics.
  4. UA-roots Awery — palpable conflict? Якщо Awery планує own UA-launch через Київ R&D — конкуренція не партнерство. Action: Phase 4-5 — перші розмови саме для калібрування цього сигналу.
  5. Awery API documentation gating model — public dev portal absent. Action: Phase 9+ — після MoU signed, отримати NDA + access.
  6. WIN actual subscription pricing — не на сайті. Action: Phase 9+ — outreach call.
  7. ICS2 R1+R2 для air ENS — який ITSP (Descartes / AEB) працює з air domain. Action: Phase 9+ — vendor selection після Awery integration ready.

§ 9. Linkbacks


Phase 3 implementation-ready spec — 2026-05-12. Phase 9+ deferred to post-Awery partnership conversation.