Skip to content

시설 작업지시 프론트엔드 메인테이너 매뉴얼

정식 소비 화면

  • /facility/task/equipment/task/generalsubjectKind='equipment'
  • /facility/task/unit/task/generalsubjectKind='unit'

IndexView.vuesrc/components/facility/work-order/WorkOrderHeaderOrg.vueWorkOrderMainOrg.vue를 같은 방식으로 소비합니다. 과거 maintenance task/setting 및 task setting 경로는 src/router/facilityWorkOrderRoutes.js의 함수형 redirect를 사용해 query와 hash를 보존한 채 정식 경로로 이동합니다. facilityNav.js와 AI 기능 카탈로그에는 maintenance 작업지시 링크를 두지 않습니다.

컴포넌트 흐름

text
canonical IndexView(subjectKind)
  -> WorkOrderHeaderOrg (현재 Office 사실만 표시)
  -> WorkOrderMainOrg
    -> useFacilityWorkOrders(subjectKind)
      -> resolveFacilityWorkOrderRepo()
        -> Supabase adapter 또는 unavailable empty adapter
        -> facility_work_orders list
        -> get_office_operational_participants() (optional ledger)
        -> facility_assets 또는 property_spaces (optional exact target ledger)
    -> WorkOrderTableOrg
      -> title click: exact row -> SheetWorkOrderDetailArt.open(row)
      -> requested: SheetAssignWorkOrderArt -> transition(row, participant)
      -> later status: transition(row)
    -> SheetCreateWorkOrderArt -> create(input)

화면은 Supabase client나 RPC를 직접 호출하지 않습니다. Company/Office scope는 useAccountContext()에서 가져오고 repository가 snake_case API 계약을 camelCase UI 모델로 정규화합니다.

주요 파일

  • src/components/facility/work-order/WorkOrderMainOrg.vue
    • 설비·공간 공통 실제 원장 orchestrator
    • loading/error/unavailable/real-empty 분리
    • participant partial failure 경고 분리
    • exact target partial failure를 분리하고 manual subjectRef 생성 유지
    • 선택 ID 추적과 Office 변경 시 생성·상세·배정 시트 무효화
  • src/components/facility/work-order/WorkOrderTableOrg.vue
    • 대상 유형 → 작업지시 등록코드/작업명 → 대상 참조 → 상태 등 canonical 열 순서
    • 작업명 클릭으로 정확한 row 전달
    • requested 배정과 이후 단조 전이
  • src/components/facility/maintenance/SheetCreateWorkOrderArt.vue
    • 설비·공간 공용 create 전용 3xl 집중 시트
    • 대상 참조·작업명 valid, dirty 저장 gate
    • 설비 자산/프로퍼티 공간 정본 selector와 manual fallback
    • urgent|high|normal|low 우선순위
  • src/components/facility/maintenance/SheetWorkOrderDetailArt.vue
    • open(workOrder)로 주입한 정확한 선택 row와 authoritative timestamp 이력
    • 관리코드는 우측 상단에만 작게 표시
    • sheet-footer에서 선택 row의 다음 동작 emit
  • src/components/facility/maintenance/SheetAssignWorkOrderArt.vue
    • 2xl 집중 폭의 Office actor/party 단일 선택
    • 저장 중 닫기·중복 제출 차단; Office scope 폐기 때만 force close
  • src/composables/useFacilityWorkOrders.js
    • 목록·participant·subject ledger의 Promise.allSettled 분리
    • Company·Office scope sequence, load/command sequence
    • stale load success/error와 stale create/transition/pending 차단
  • src/composables/facilityWorkOrderRepo.js
    • 실제 SELECT/create RPC/transition RPC 계약과 row 정규화
    • 비-test no-config의 unavailable empty adapter

제품 독립성과 선택 연결

작업지시의 subjectRef는 항상 필수인 현장 참조 문자열입니다. facilityAssetIdpropertySpaceId는 선택 exact link이고 둘 다 없어도 목록·생성·단조 상태 흐름은 독립 동작합니다.

  • 자산/공간 연결: 설비 화면은 facility asset, 공간 화면은 platform-core property space selector를 제공합니다. selector 실패 시 별도 경고를 표시하고 manual subjectRef 입력은 유지합니다.
  • 담당자 연결: actor/party directory는 optional ledger입니다. 조회 실패 시 목록·생성은 유지하고 배정만 후보 복구가 필요합니다.
  • HR enrichment: participant snapshot 표시 보강만 허용합니다. HR employee/assignment를 facility repo의 필수 FK나 UI gate로 되돌리지 않습니다.

repository와 mutation 계약

list({ companyId, officeId, subjectKind })는 세 범위를 모두 query에 명시합니다.

create(input)은 현재 Company·Office와 고정 subjectKind에 다음 폼 값을 더합니다.

  • subjectRef, title 필수
  • facilityAssetId 또는 propertySpaceId 선택. selector를 쓰지 않으면 둘 다 null
  • description, registrationCode 선택
  • priority 기본 normal
  • 사용자 동작마다 새 requestKey

성공 행은 현재 scope 목록 선두에 중복 없이 삽입합니다. 관리코드, 초기 상태·revision·시간과 actor는 클라이언트가 입력하지 않습니다.

transition(input)companyId, workOrderId, 다음 toStatus, 화면 row의 expectedRevision, 배정 시 actor 또는 party ID 하나, 새 requestKey를 전송합니다. 성공 시 현재 scope 배열의 같은 ID만 교체합니다.

Office가 바뀌면 scopeSequence, loadSequence, commandSequence가 모두 증가하고 배열·pending·오류를 초기화합니다. 이전 scope 응답은 null로 끝나므로 Main은 stale 성공을 표시하지 않습니다. scope watch는 생성·상세·배정 시트를 강제 종료하고, workOrders에서 선택 ID가 사라질 때도 상세와 배정 시트를 즉시 닫습니다.

UI 상태와 게이팅

  • resolving/loading: 실제 목록 조회 중 문구
  • available + empty: 샘플 fallback 없는 실제 빈 상태와 생성 안내
  • work-order error: 오류 + 다시 시도; 빈 상태를 함께 표시하지 않음
  • unavailable: 연결 안내; create/transition 도구 숨김
  • participant error: 실제 목록과 create 유지, 별도 경고와 participant retry
  • subject error: 실제 목록과 create 유지, manual subjectRef fallback
  • requested: 담당자 배정
  • assigned: 작업 시작
  • in_progress: 작업 완료
  • completed: 검수 완료
  • verified: 종결, action 없음

전이 중인 행과 상세 action은 같은 transitioningId로 중복 실행을 차단합니다. 목록과 상세는 같은 row 객체를 전달하며, 성공한 transition은 양쪽에 같은 서버 응답을 반영합니다. 정적 샘플 상세, fake 업체·비용, checkbox, 무동작 검색·필터·다운로드·페이지네이션을 canonical graph에 다시 추가하지 않습니다.

테스트

  • src/composables/__tests__/facilityWorkOrderRepo.spec.js: 범위 query, RPC payload, normalize, error/no-config 계약
  • src/composables/__tests__/useFacilityWorkOrders.spec.js: partial ledger와 Office stale load/create/transition guard
  • src/composables/__tests__/facilityWorkOrderMigration.spec.js: schema/RLS/RPC/상태 머신/감사 정적 계약
  • src/composables/__tests__/facilityWorkOrderUiContract.spec.js: 공용 canonical UI와 exact selected action
  • src/composables/__tests__/facilityWorkOrderReleaseContract.spec.js: redirect query/hash, nav/AI dead link 0, fake UI 제거
  • src/components/facility/maintenance/__tests__/FacilityWorkOrderSheets.spec.js: create valid/dirty/payload, selected detail/action
  • supabase/tests/facility_work_orders_smoke.sql: disposable DB 실행형 계약
  • src/composables/__tests__/facilityClosureLoopMigration.spec.js: stable target, source snapshot, grant 정적 계약
  • supabase/tests/facility_inspection_work_order_closure_loop_smoke.sql: exact target과 점검 폐쇄루프 rollback smoke