АСК Легарус

Поиск

Релиз

Содержание

Нужна помощь?

Не нашли ответ на свой вопрос? Свяжитесь с нашей службой поддержки.

Обратиться в поддержку

Runbook — mobile contract v2 cutover

Обновлено: 09 Октябрь 2026 Версия: 2.4.0

Зеркало operational runbook из репозитория ask (documentation/technical/event-center/runbook-mobile-contract-v2.md). Контрактные таблицы wire: event-center-mobile-contract-v2.

Runbook: mobile contract v2 cutover (Event Center)

Operational cutover for Event Center mobile contract v2 on shared/prod-like stands. Mirror in ask-doc: opisanie-api-ask-legarus/runbook-mobile-contract-v2.md. Wire mapping / RR / capabilities: ask-doc opisanie-api-ask-legarus/event-center-mobile-contract-v2.md.

1. Order of operations

  1. Migrate schema + data (0010_mobile_contract_v2_fields): bash source .venv/bin/activate && python manage.py migrate event_center Migration adds nullable resolved_at / last_action_key, counters v2 columns (default 0), and backfills resolved_at=updated_at for terminal action_status rows (completed / expired / cancelled).
  2. Reconcile counters (defaults 0 are not semantic until recalculated): bash source .venv/bin/activate && python manage.py reconcile_inbox_counters_v2 Scope: users with any non-zero stored counter and/or non-archived personal recipients. Full active-user pass: --all. Single user: --user-id N. Dry-run: --dry-run. Alternative after search rebuild (all active users): bash source .venv/bin/activate && python manage.py rebuild_event_center_indexes --counters-only
  3. Normalize legacy Inbox Open targets (optional but recommended after Open/entity fixes — stale ACTION cards, wrong parent entity, unread INFO leftovers): bash source .venv/bin/activate && python scripts/normalize_inbox_state.py # dry-run source .venv/bin/activate && python scripts/normalize_inbox_state.py --apply source .venv/bin/activate && python scripts/normalize_inbox_state.py --apply --user-id N # Steps include CRM leads, SD requests, KPI approvals, absences, workhours, constructor, counters. Among other steps, remaps:
  4. WH: servicedesk/request → workhour_record (Open → overtime card);
  5. approvals: finance/contract → approval_participant, projects/project → team_member_approval / baseline_approval when payload has approval_entity_type / approval_entity_id. Then recalculates counters (unless --skip-counters).
  6. Deploy code that exposes bootstrap event_center_version ≥ 2 and HTTP contract parsing.
  7. Bootstrap version 2 — mobile clients read event_center_version from bootstrap / /.well-known/ask-mobile and only then enable v2 Inbox behaviour.

Optional env (not required): ASK_EC_CONTRACT_DEFAULT=1 for stands that want an explicit default when the header is absent (HTTP without header remains contract 1).

2. Flutter client

After bootstrap reports event_center_version ≥ 2, send:

X-ASK-EC-Contract: 2

on Event Center Inbox / actions / counters / search API calls. Do not send contract 2 before version gate.

3. Web / HTTP vs WebSocket

Channel Contract
HTTP without X-ASK-EC-Contract Contract 1 (as-is ORM / legacy shape)
HTTP with X-ASK-EC-Contract: 2 Contract 2 (wire dual DTO)
WebSocket / sync gap recovery Already dual wire (no header default=1)

4. Handler waves (Pilot → Wave 2 → Wave 3)

Generic execute protocol (available_actions + POST …/actions/{key}/) ships with v2. Handler registry is enabled by wave. Capability generic_approval_execute=true means the protocol is ready — not that every Matrix type is in-inbox.

Wave event_type (taxonomy)
Pilot absence.approval_required, contract.approval_assigned
Wave 2 task.duedate_transfer, project.team_approval_required, project.baseline_approval_required, kb.approval_required, kb.page_acknowledge
Wave 3 servicedesk.kpi_approval_required, workhour.approval_required, workhour.tech_approval_required, workhour.client_approval_required, other ACTION types with approve/reject in EventTypeDefinition.actions

Types outside the registered wave return available_actions=[] and execute 409 action_not_available — expected.

5. Rollback

  • Flip bootstrap / feature so clients stay on contract 1 (no header / version gate below 2). Nullable v2 columns remain safe; no destructive DROP required.
  • Counters can be re-reconciled after rollback if drift is suspected: manage.py reconcile_inbox_counters_v2 --all.

6. Smoke (task 3.2)

Preferred (LiveServer / runserver-equivalent):

source .venv/bin/activate && python manage.py test event_center.tests.test_mobile_contract_runtime_smoke --settings=config.test_settings

Covers: EC enabled bootstrap version 2, EC disabled graceful bootstrap, HTTP contract 1 vs 2 Inbox, non-pilot execute 409 without 500.

If LiveServer is unavailable in the environment, document and run a management smoke entrypoint when present (smoke_mobile_contract_v2); otherwise use the test module above against shared DB.

7. AutoResolve and last_action_key

System close / AutoResolve with overwrite clears claim: last_action_key=NULL on successful terminal write. User execute paths that omit overwrite leave the key unchanged. Do not treat NULL key after AutoResolve as corruption.

8. Push payload

Push data keeps as-is identity fields and adds wire purpose / severity / mobile_badge_total. Delivery must not mutate Inbox state. Prefer running push-path smoke from event_center.tests.test_runtime_smoke / acceptance push tests after cutover.

9. Optional index (not a blocker)

Composite index (user, action_status, resolution_reason) for heavy status=auto_resolved search is optional. Existing (user, action_status, …) indexes are enough for first ship. Add a separate migration 0011_… only if staging shows slow auto_resolved filters; otherwise skip.

10. Inbox Open targets (entity → URL)

Открыть on an ACTION card resolves via entity adapters / entity_links, not the parent document. Canonical targets after product fixes:

Domain entity_module / entity_type Open
Overtime / WH workflow servicedesk / workhour_record workhour_detail
Contract approval finance / approval_participant contract_approval_decide
Project team approval projects / team_member_approval team_approval_list
Baseline approval projects / baseline_approval baseline_approval_list
Absence approval personal / absence (UUID) absence_review
Supply specification trading / specification specification_detail

Legacy rows still pointing Open at parent request / contract / project are rewritten by scripts/normalize_inbox_state.py (steps workhour_entity, approval_entity).

11. Verification checklist

  • [ ] showmigrations event_center — 0010_mobile_contract_v2_fields applied
  • [ ] reconcile_inbox_counters_v2 completed; spot-check mobile_badge_total === COUNT open ACTION visible for a sample user
  • [ ] (If remapping legacy Open) normalize_inbox_state.py --apply dry-run reviewed
  • [ ] Bootstrap returns event_center_version ≥ 2 with EC enabled
  • [ ] Flutter sends X-ASK-EC-Contract: 2 only after version gate
  • [ ] Smoke 3.2 green
  • [ ] Pilot execute works; Wave 2/3 types outside registry → empty actions / 409