@dssp/dkpi 1.0.0-alpha.71 → 1.0.0-alpha.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/config/config.development.js +2 -1
  2. package/config/config.production.js +2 -1
  3. package/dist-client/entries/auth/checkin.d.ts +38 -0
  4. package/dist-client/entries/auth/checkin.js +546 -0
  5. package/dist-client/entries/auth/checkin.js.map +1 -0
  6. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.d.ts +1 -1
  7. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js +17 -3
  8. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js.map +1 -1
  9. package/dist-client/pages/kpi-value/kpi-value-list-page.js +21 -31
  10. package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -1
  11. package/dist-client/pages/sv-project-complete.d.ts +1 -0
  12. package/dist-client/pages/sv-project-complete.js +21 -2
  13. package/dist-client/pages/sv-project-complete.js.map +1 -1
  14. package/dist-client/pages/sv-project-detail.d.ts +1 -0
  15. package/dist-client/pages/sv-project-detail.js +55 -9
  16. package/dist-client/pages/sv-project-detail.js.map +1 -1
  17. package/dist-client/pages/sv-user-management.d.ts +1 -0
  18. package/dist-client/pages/sv-user-management.js +5 -0
  19. package/dist-client/pages/sv-user-management.js.map +1 -1
  20. package/dist-client/route.d.ts +1 -1
  21. package/dist-client/route.js +13 -2
  22. package/dist-client/route.js.map +1 -1
  23. package/dist-client/shared/domain-context.d.ts +7 -0
  24. package/dist-client/shared/domain-context.js +13 -0
  25. package/dist-client/shared/domain-context.js.map +1 -0
  26. package/dist-client/tsconfig.tsbuildinfo +1 -1
  27. package/dist-client/viewparts/menu-tools.js +26 -10
  28. package/dist-client/viewparts/menu-tools.js.map +1 -1
  29. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js +1 -2
  30. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js.map +1 -1
  31. package/dist-server/service/kpi-value/kpi-value-query.d.ts +2 -2
  32. package/dist-server/service/kpi-value/kpi-value-query.js +5 -11
  33. package/dist-server/service/kpi-value/kpi-value-query.js.map +1 -1
  34. package/dist-server/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +3 -3
  36. package/schema.graphql +727 -6
  37. package/translations/en.json +5 -1
  38. package/translations/ko.json +5 -1
package/schema.graphql CHANGED
@@ -838,6 +838,7 @@ type Attachment {
838
838
  refType: String
839
839
  size: String!
840
840
  tags: Object
841
+ thumbnail: String
841
842
  updatedAt: DateTimeISO!
842
843
  updater: User
843
844
  }
@@ -1151,12 +1152,22 @@ type Board {
1151
1152
  """
1152
1153
  sortOrder: Float
1153
1154
 
1155
+ """
1156
+ Source ImportSession id (board-import) when this board was generated from a drawing/image import.
1157
+ """
1158
+ sourceImportSessionId: String
1159
+
1154
1160
  """The state of the board, can be 'draft' or 'released'."""
1155
1161
  state: String
1156
1162
 
1157
1163
  """A base64 encoded thumbnail image of the board."""
1158
1164
  thumbnail: String
1159
1165
 
1166
+ """
1167
+ Timestamp of the last thumbnail generation. Separate lifecycle from updatedAt; only changes when the thumbnail image itself is regenerated.
1168
+ """
1169
+ thumbnailUpdatedAt: DateTimeISO
1170
+
1160
1171
  """The type of the board, can be 'main', 'sub', or 'popup'."""
1161
1172
  type: String
1162
1173
 
@@ -1170,6 +1181,120 @@ type Board {
1170
1181
  version: Float
1171
1182
  }
1172
1183
 
1184
+ input BoardAIChatInput {
1185
+ """
1186
+ Component categories to surface (e.g. ["3D", "form"]). Subset filter for groupings exposed in component-schemas.
1187
+ """
1188
+ categories: [String!]
1189
+
1190
+ """
1191
+ Component schemas — array of { type, description?, group?, properties? } so the LLM knows valid props per type.
1192
+ """
1193
+ componentSchemas: JSON
1194
+
1195
+ """Current BoardModel JSON."""
1196
+ currentBoard: JSON
1197
+
1198
+ """
1199
+ Component types the LLM is allowed to emit (e.g. ["rect", "label"]). Constrains generation to the current solution.
1200
+ """
1201
+ knownTypes: [String!]
1202
+
1203
+ """
1204
+ Max output tokens override per LLM call. Falls back to assistant default when omitted.
1205
+ """
1206
+ maxTokens: Float
1207
+
1208
+ """
1209
+ Explicit #mention picks from popup — {token, refid}. User text stays clean (#token only); these picks let server resolve deterministically without exposing refid in the user-visible message. Tokens not in this list fall back to free name/id/type matching.
1210
+ """
1211
+ mentions: [BoardAIMentionPickInput!]
1212
+
1213
+ """
1214
+ Conversation history (latest user message at the end). For persisted sessions, only the last user message is appended; older are loaded from DB.
1215
+ """
1216
+ messages: [BoardAILLMMessageInput!]!
1217
+
1218
+ """
1219
+ AI model identifier override (e.g. "claude-opus-4-7"). Falls back to the configured default when omitted.
1220
+ """
1221
+ model: String
1222
+
1223
+ """
1224
+ Capability scopes the AI is allowed to use (e.g. 'create', 'edit', 'style'). Filters which tools are exposed to the LLM.
1225
+ """
1226
+ scopes: [String!]
1227
+
1228
+ """
1229
+ Refids of components currently selected in the modeller (universal numeric handle, things-scene auto-assigned). For "selected" / "선택한" intent. Note: distinct from `id` which is a data-binding name.
1230
+ """
1231
+ selectedRefids: [Int!]
1232
+
1233
+ """
1234
+ ChatSession id. Omit for ad-hoc (no persistence). When given, messages/patches are persisted.
1235
+ """
1236
+ sessionId: String
1237
+
1238
+ """
1239
+ Sampling temperature override. Falls back to assistant default when omitted.
1240
+ """
1241
+ temperature: Float
1242
+ }
1243
+
1244
+ type BoardAIChatOutput {
1245
+ """
1246
+ Ephemeral scene actions (selection/view/mode) — sequence of BoardActionOp. Applied via board-action-execute event on the host. Distinct from `patch` which carries persistent model changes.
1247
+ """
1248
+ actions: JSON
1249
+
1250
+ """Persisted ChatMessage id of the AI reply."""
1251
+ assistantMessageId: String
1252
+
1253
+ """AI client identifier (provider:model)."""
1254
+ clientId: String!
1255
+
1256
+ """Clarifying question when input is ambiguous."""
1257
+ followUp: String
1258
+
1259
+ """BoardEditPatch."""
1260
+ patch: JSON
1261
+
1262
+ """Persisted PatchEntry id (when patch was generated)."""
1263
+ patchId: String
1264
+
1265
+ """Conversational reply."""
1266
+ reply: String!
1267
+
1268
+ """Echo of session id (when persisted)."""
1269
+ sessionId: String
1270
+
1271
+ """
1272
+ Tool usages collected during agentic loop — sequence of {name, arguments, result, kind}. UI fold-able box for transparency / debug.
1273
+ """
1274
+ toolUsages: JSON
1275
+
1276
+ """Persisted ChatMessage id of the user input."""
1277
+ userMessageId: String
1278
+ }
1279
+
1280
+ input BoardAILLMMessageInput {
1281
+ """Message content"""
1282
+ content: String!
1283
+
1284
+ """Role: 'user' or 'assistant'"""
1285
+ role: String!
1286
+ }
1287
+
1288
+ input BoardAIMentionPickInput {
1289
+ """
1290
+ Refid explicitly picked from popup. Server uses this for deterministic resolution — bypasses fallback name/id/type matching for this token.
1291
+ """
1292
+ refid: Int!
1293
+
1294
+ """Token used by user (e.g. "경광등1" — the part after #)."""
1295
+ token: String!
1296
+ }
1297
+
1173
1298
  """Represents a board that a user has marked as a favorite."""
1174
1299
  type BoardFavorite {
1175
1300
  """The timestamp when the board was created."""
@@ -1210,12 +1335,22 @@ type BoardFavorite {
1210
1335
  """
1211
1336
  sortOrder: Float
1212
1337
 
1338
+ """
1339
+ Source ImportSession id (board-import) when this board was generated from a drawing/image import.
1340
+ """
1341
+ sourceImportSessionId: String
1342
+
1213
1343
  """The state of the board, can be 'draft' or 'released'."""
1214
1344
  state: String
1215
1345
 
1216
1346
  """A base64 encoded thumbnail image of the board."""
1217
1347
  thumbnail: String
1218
1348
 
1349
+ """
1350
+ Timestamp of the last thumbnail generation. Separate lifecycle from updatedAt; only changes when the thumbnail image itself is regenerated.
1351
+ """
1352
+ thumbnailUpdatedAt: DateTimeISO
1353
+
1219
1354
  """The type of the board, can be 'main', 'sub', or 'popup'."""
1220
1355
  type: String
1221
1356
 
@@ -1307,6 +1442,16 @@ type BoardList {
1307
1442
  total: Int!
1308
1443
  }
1309
1444
 
1445
+ type BoardMetaSuggestion {
1446
+ """
1447
+ Suggested detailed description — combines user prompt, AI importStrategy narrative, and category distribution stats.
1448
+ """
1449
+ description: String!
1450
+
1451
+ """Suggested short board name (collision-free with current domain)."""
1452
+ name: String!
1453
+ }
1454
+
1310
1455
  """Input for updating (patching) an existing board."""
1311
1456
  input BoardPatch {
1312
1457
  """The new description for the board."""
@@ -1701,6 +1846,113 @@ input BuildingPatch {
1701
1846
  name: String
1702
1847
  }
1703
1848
 
1849
+ """A single chat message in a ChatSession."""
1850
+ type ChatMessage {
1851
+ """Message content"""
1852
+ content: String!
1853
+
1854
+ """Creation timestamp."""
1855
+ createdAt: DateTimeISO
1856
+
1857
+ """User who triggered this message."""
1858
+ creator: User
1859
+
1860
+ """Soft delete timestamp."""
1861
+ deletedAt: DateTimeISO
1862
+ id: ID
1863
+
1864
+ """
1865
+ Id of the message this one is in-response-to / continues. Enables linear / branching / tree structures.
1866
+ """
1867
+ parentMessageId: String
1868
+
1869
+ """ImportSession.id this message triggered (if any)."""
1870
+ relatedImportSessionId: String
1871
+
1872
+ """PatchEntry.id this message triggered (if any)."""
1873
+ relatedPatchId: String
1874
+
1875
+ """'user' | 'assistant' | 'system'"""
1876
+ role: String!
1877
+
1878
+ """
1879
+ Tool usage trace — array of {name, arguments, result, kind}. Only on assistant messages.
1880
+ """
1881
+ toolUsagesJson: JSON
1882
+
1883
+ """Last update timestamp (relevant once message editing is supported)."""
1884
+ updatedAt: DateTimeISO
1885
+
1886
+ """Last user to update this message (for future edit support)."""
1887
+ updater: User
1888
+ }
1889
+
1890
+ """AI 협력 세션 — Board 와 결합. 한 보드에 여러 세션 가능 (thread / 사용자별 / 컨텍스트별 등 미래 확장)."""
1891
+ type ChatSession {
1892
+ aiClientId: String
1893
+
1894
+ """
1895
+ Connected Board id. Multiple sessions per board allowed (future: threads / per-user / contexts).
1896
+ """
1897
+ boardId: String
1898
+ createdAt: DateTimeISO
1899
+
1900
+ """User who created this session."""
1901
+ creator: User
1902
+ domain: Domain
1903
+ id: ID
1904
+
1905
+ """Compressed summary of older messages (for token saving)."""
1906
+ lastSummary: String
1907
+
1908
+ """User-given name of this session (tab label / identification)."""
1909
+ name: String
1910
+ updatedAt: DateTimeISO
1911
+
1912
+ """User who last updated this session."""
1913
+ updater: User
1914
+ }
1915
+
1916
+ """
1917
+ Participant of a ChatSession — links a User to a session with a role. Foundation for multi-user chat / per-user filtering / member display.
1918
+ """
1919
+ type ChatSessionParticipant {
1920
+ """Joined-at timestamp."""
1921
+ createdAt: DateTimeISO
1922
+
1923
+ """
1924
+ User who created this participant record (typically session owner who invited).
1925
+ """
1926
+ creator: User
1927
+
1928
+ """Soft delete (= left session) timestamp."""
1929
+ deletedAt: DateTimeISO
1930
+
1931
+ """Domain to which this participant belongs."""
1932
+ domain: Domain
1933
+
1934
+ """Unique participant id."""
1935
+ id: ID!
1936
+
1937
+ """Last seen / activity timestamp (presence indicator)."""
1938
+ lastSeenAt: DateTimeISO
1939
+
1940
+ """Role of this participant: owner | member | viewer."""
1941
+ role: String!
1942
+
1943
+ """The ChatSession this participation belongs to."""
1944
+ session: ChatSession
1945
+
1946
+ """Last update timestamp (role change / lastSeenAt bump)."""
1947
+ updatedAt: DateTimeISO
1948
+
1949
+ """Last user to update this participant record (e.g., role change)."""
1950
+ updater: User
1951
+
1952
+ """The user participating in the session."""
1953
+ user: User
1954
+ }
1955
+
1704
1956
  type Checklist {
1705
1957
  buildingInspection: BuildingInspection!
1706
1958
  checklistAttachments(description: String): [Attachment!]!
@@ -2203,6 +2455,68 @@ type ConnectorType {
2203
2455
  taskPrefixes: [String!]
2204
2456
  }
2205
2457
 
2458
+ type ConstructionChecklistTemplate {
2459
+ constructionChecklistTemplateItems: [ConstructionChecklistTemplateItem!]
2460
+ constructionDetailTypeId: String!
2461
+ constructionTypeId: String!
2462
+ createdAt: DateTimeISO
2463
+ creator: User
2464
+ deletedAt: DateTimeISO
2465
+ domain: Domain
2466
+ id: ID!
2467
+ updatedAt: DateTimeISO
2468
+ updater: User
2469
+ }
2470
+
2471
+ type ConstructionChecklistTemplateItem {
2472
+ constructionChecklistTemplate: ConstructionChecklistTemplate
2473
+ createdAt: DateTimeISO
2474
+ creator: User
2475
+ criteriaRequestStatus: CriteriaRequestStatus
2476
+ id: ID!
2477
+ inspctionCriteria: String
2478
+ mainType: String
2479
+ name: String!
2480
+ recommendation1: String
2481
+ recommendation2: String
2482
+ recommendation3: String
2483
+ recommendation4: String
2484
+ recommendation5: String
2485
+ sequence: Int
2486
+ updatedAt: DateTimeISO
2487
+ updater: User
2488
+ }
2489
+
2490
+ type ConstructionChecklistTemplateItemList {
2491
+ items: [ConstructionChecklistTemplateItem!]!
2492
+ total: Int!
2493
+ }
2494
+
2495
+ input ConstructionChecklistTemplateItemPatch {
2496
+ id: ID
2497
+ inspctionCriteria: String
2498
+ mainType: String
2499
+ name: String
2500
+ recommendation1: String
2501
+ recommendation2: String
2502
+ recommendation3: String
2503
+ recommendation4: String
2504
+ recommendation5: String
2505
+ sequence: Int
2506
+ }
2507
+
2508
+ type ConstructionChecklistTemplateList {
2509
+ items: [ConstructionChecklistTemplate!]!
2510
+ total: Int!
2511
+ }
2512
+
2513
+ input ConstructionChecklistTemplatePatch {
2514
+ constructionDetailTypeId: String
2515
+ constructionTypeId: String
2516
+ cuFlag: String
2517
+ id: ID
2518
+ }
2519
+
2206
2520
  """세부 공종 타입"""
2207
2521
  type ConstructionDetailType {
2208
2522
  constructionType: ConstructionType
@@ -2237,6 +2551,7 @@ type ConstructionType {
2237
2551
  domain: Domain
2238
2552
  id: ID!
2239
2553
  name: String
2554
+ projectType: String
2240
2555
  updatedAt: DateTimeISO
2241
2556
  updater: User
2242
2557
  }
@@ -2251,6 +2566,7 @@ input ConstructionTypePatch {
2251
2566
  description: String
2252
2567
  id: ID
2253
2568
  name: String
2569
+ projectType: String
2254
2570
  }
2255
2571
 
2256
2572
  """Entity for Contact"""
@@ -3535,6 +3851,27 @@ type DomainList {
3535
3851
  total: Int
3536
3852
  }
3537
3853
 
3854
+ """An ownership record binding a User to a Domain (multi-owner support)."""
3855
+ type DomainOwner {
3856
+ """Domain that the user owns."""
3857
+ domain: Domain!
3858
+
3859
+ """When the ownership was granted."""
3860
+ grantedAt: DateTimeISO!
3861
+
3862
+ """User who granted this ownership (audit)."""
3863
+ grantedBy: User
3864
+
3865
+ """Unique identifier."""
3866
+ id: ID!
3867
+
3868
+ """Optional reason/memo for granting ownership."""
3869
+ reason: String
3870
+
3871
+ """User who owns the domain."""
3872
+ user: User!
3873
+ }
3874
+
3538
3875
  """Input type for updating an existing domain entity."""
3539
3876
  input DomainPatch {
3540
3877
  """Additional attributes for the domain in key-value pairs."""
@@ -4094,6 +4431,70 @@ input GroupPatch {
4094
4431
  name: String
4095
4432
  }
4096
4433
 
4434
+ input ImportBoardAsyncInput {
4435
+ """Apply Stage 4 (data binding)."""
4436
+ applyBinding: Boolean
4437
+
4438
+ """
4439
+ Attachment id of the source drawing file (uploaded via attachment-base).
4440
+ """
4441
+ attachmentId: String!
4442
+
4443
+ """ChatSession id when triggered from board-ai chat."""
4444
+ chatSessionId: String
4445
+
4446
+ """Flip Y axis (CAD Y-up → scene Y-down)."""
4447
+ flipY: Boolean
4448
+
4449
+ """Normalize coordinates so minX,minY=0"""
4450
+ normalizeOrigin: Boolean
4451
+
4452
+ """Adapter parse options (excludeLayers, maxEntities, ...)."""
4453
+ parseOptions: JSON
4454
+
4455
+ """Scale factor (e.g. 1 for mm:1unit)."""
4456
+ scale: Float
4457
+
4458
+ """Registry scopes to use (board-import)."""
4459
+ scopes: [String!]
4460
+
4461
+ """
4462
+ User-provided context / hints about the drawing — passed to VLM as additional guidance. e.g. "fab lithography zone, central rectangles are stockers, thin lines are OHT rails."
4463
+ """
4464
+ userPrompt: String
4465
+ }
4466
+
4467
+ """도면 → 보드 변환 작업의 영속 단위 (비동기 진행상태 추적)."""
4468
+ type ImportSession {
4469
+ """Attachment id (the source drawing file)"""
4470
+ attachmentId: String!
4471
+
4472
+ """ChatSession id when triggered from chat (board-ai)."""
4473
+ chatSessionId: String
4474
+ completedAt: DateTimeISO
4475
+ createdAt: DateTimeISO
4476
+ creator: User
4477
+ domain: Domain
4478
+ id: ID
4479
+ message: String
4480
+
4481
+ """Options used (parsed JSON)."""
4482
+ options: JSON
4483
+
4484
+ """Progress percentage 0..100"""
4485
+ progress: Float!
4486
+
4487
+ """Result (parsed JSON): { boardModel, stats, warnings }."""
4488
+ result: JSON
4489
+
4490
+ """queued | parsing | mapping | assembling | binding | completed | failed"""
4491
+ status: String!
4492
+
4493
+ """Total entities counted (when known)."""
4494
+ totalEntities: Int
4495
+ updatedAt: DateTimeISO
4496
+ }
4497
+
4097
4498
  """
4098
4499
  Enumeration for inherited value types: None, Only, or Include. Used to specify how values are inherited in queries or filters.
4099
4500
  """
@@ -4267,6 +4668,11 @@ enum IssueStatus {
4267
4668
  STATUS_B
4268
4669
  }
4269
4670
 
4671
+ """
4672
+ The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).
4673
+ """
4674
+ scalar JSON @specifiedBy(url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf")
4675
+
4270
4676
  """
4271
4677
  A field whose value is a JSON Web Token (JWT): https://jwt.io/introduction.
4272
4678
  """
@@ -4573,7 +4979,7 @@ input KpiMetricPatch {
4573
4979
  """데이터 수집 방식"""
4574
4980
  collectType: KpiMetricCollectType
4575
4981
  cuFlag: String
4576
- dataSetId: ID
4982
+ dataSet: ObjectRef
4577
4983
  description: String
4578
4984
  fieldName: String
4579
4985
  id: ID
@@ -4616,7 +5022,7 @@ type KpiMetricValue {
4616
5022
  """
4617
5023
  org: String
4618
5024
  periodType: KpiPeriodType!
4619
- project: Project!
5025
+ project: Project
4620
5026
  unit: String
4621
5027
  updatedAt: DateTimeISO
4622
5028
  updater: User
@@ -5407,6 +5813,33 @@ input ManagerPatch {
5407
5813
  userId: ID
5408
5814
  }
5409
5815
 
5816
+ input MaterializeImportSessionInput {
5817
+ """Optional Board description."""
5818
+ description: String
5819
+
5820
+ """Optional Group id to attach the Board to."""
5821
+ groupId: ID
5822
+
5823
+ """New Board name."""
5824
+ name: String!
5825
+
5826
+ """ImportSession id (must be in completed state)."""
5827
+ sessionId: ID!
5828
+
5829
+ """
5830
+ Base64 thumbnail. If omitted, board-service default empty thumbnail is used.
5831
+ """
5832
+ thumbnail: String
5833
+
5834
+ """Board type — 'main' | 'sub' | 'popup'. Default 'main'."""
5835
+ type: String
5836
+
5837
+ """
5838
+ ImportSession 의 결과 시안 중 하나의 id. 'as-is' / 'scene' / 'auto-fit'. 미지정 시 default variant (보통 'scene') 사용.
5839
+ """
5840
+ variantId: String
5841
+ }
5842
+
5410
5843
  """Entity for Menu"""
5411
5844
  type Menu {
5412
5845
  buttons: [MenuButton!]!
@@ -5785,6 +6218,9 @@ type Mutation {
5785
6218
  username: String!
5786
6219
  ): Boolean!
5787
6220
 
6221
+ """Add a user as owner of the current domain."""
6222
+ addDomainOwner(reason: String, username: String!): DomainOwner!
6223
+
5788
6224
  """To apply to all building inspection"""
5789
6225
  applyToAllBuildingInspection(buildingInspectionId: String!): Boolean!
5790
6226
 
@@ -5805,6 +6241,14 @@ type Mutation {
5805
6241
  """
5806
6242
  attachContact(contactId: String!, id: String!): Employee!
5807
6243
 
6244
+ """
6245
+ 썸네일이 없는 기존 첨부파일들에 대해 서버에서 썸네일을 일괄 생성한다. 한 호출당 limit 개까지만 처리하며, remaining > 0 이면 반복 호출 필요.
6246
+ """
6247
+ backfillAttachmentThumbnails(limit: Int = 20): ThumbnailBackfillResult!
6248
+
6249
+ """AI 주도 보드 모델링 — 자연어 채팅으로 보드 생성·구조편집·스타일링. sessionId 로 영속 컨텍스트."""
6250
+ boardAIChat(input: BoardAIChatInput!): BoardAIChatOutput!
6251
+
5808
6252
  """Bulk create or update KPI org-scope mappings."""
5809
6253
  bulkUpsertKpiOrgScopes(
5810
6254
  """Array of org-scope mapping data for bulk upsert."""
@@ -5893,6 +6337,16 @@ type Mutation {
5893
6337
  """Create Daily Worklog by projectId+date"""
5894
6338
  createBuildingInspectionDailyWorklog(patch: BuildingInspectionDailyWorklogNew!): BuildingInspectionDailyWorklog!
5895
6339
 
6340
+ """
6341
+ Always create a new AI chat session for a board (no idempotent reuse). For multi-session UX — 새 탭 열기.
6342
+ """
6343
+ createChatSession(
6344
+ boardId: String!
6345
+
6346
+ """Optional name (defaults to auto-generated `세션 N`)."""
6347
+ name: String
6348
+ ): ChatSession!
6349
+
5896
6350
  """To create new ChecklistItemComment"""
5897
6351
  createChecklistItemComment(checklistItemComment: NewChecklistItemComment!): ChecklistItemComment!
5898
6352
 
@@ -6074,6 +6528,9 @@ type Mutation {
6074
6528
  """프로젝트 생성"""
6075
6529
  createProject(project: NewProject!): Project!
6076
6530
 
6531
+ """프로젝트 체크리스트 생성"""
6532
+ createProjectChecklist(constructionDetailTypeId: String!, constructionTypeId: String!, items: [ProjectChecklistItemInput!]!, name: String!, projectId: String!): ProjectChecklist!
6533
+
6077
6534
  """To create new ProjectReport"""
6078
6535
  createProjectReport(projectReport: NewProjectReport!): ProjectReport!
6079
6536
 
@@ -6240,6 +6697,12 @@ type Mutation {
6240
6697
  """Deletes multiple connections by their names."""
6241
6698
  deleteConnections(names: [String!]!): Boolean!
6242
6699
 
6700
+ """공종 체크리스트 템플릿 아이템 삭제"""
6701
+ deleteConstructionChecklistTemplateItems(ids: [String!]!): Boolean!
6702
+
6703
+ """공종 기반 체크리스트 템플릿 삭제"""
6704
+ deleteConstructionChecklistTemplates(ids: [String!]!): Boolean!
6705
+
6243
6706
  """To delete multiple ConstructionDetailTypes"""
6244
6707
  deleteConstructionDetailTypes(ids: [String!]!): Boolean!
6245
6708
 
@@ -6527,6 +6990,9 @@ type Mutation {
6527
6990
  """To delete Project"""
6528
6991
  deleteProject(id: String!): Boolean!
6529
6992
 
6993
+ """프로젝트 체크리스트 삭제"""
6994
+ deleteProjectChecklists(ids: [String!]!): Boolean!
6995
+
6530
6996
  """To delete ProjectReport"""
6531
6997
  deleteProjectReport(id: String!): Boolean!
6532
6998
 
@@ -6624,6 +7090,9 @@ type Mutation {
6624
7090
  """To delete multiple WorkerTypes"""
6625
7091
  deleteWorkerTypes(ids: [String!]!): Boolean!
6626
7092
 
7093
+ """프로젝트 테넌트 강등 (Domain soft-delete, Project.code 보존)"""
7094
+ demoteProjectTenant(projectId: String!): Boolean!
7095
+
6627
7096
  """
6628
7097
  Detaches an existing contact from an employee. The employee is identified by their ID.
6629
7098
  """
@@ -6700,6 +7169,9 @@ type Mutation {
6700
7169
  attributes: [AttributeSetPatch!]!
6701
7170
  ): Boolean!
6702
7171
 
7172
+ """도면 → 보드 변환을 비동기로 시작. 즉시 ImportSession 반환, 백그라운드에서 처리."""
7173
+ importBoardAsync(input: ImportBoardAsyncInput!): ImportSession!
7174
+
6703
7175
  """Imports multiple boards from JSON files."""
6704
7176
  importBoards(files: [Upload!]!, groupId: String!, overwrite: Boolean!): [Board!]!
6705
7177
 
@@ -6843,6 +7315,11 @@ type Mutation {
6843
7315
 
6844
7316
  """Removes one or more boards from a play group."""
6845
7317
  leavePlayGroup(boardIds: [String!]!, id: String!): PlayGroup!
7318
+
7319
+ """
7320
+ 완료된 ImportSession 의 결과 boardModel 을 새 Board entity 로 영속화한다. 검수 단계 (사용자/AI 가 import 결과를 확인 후 명시적으로 호출) 에서 사용. Board.state="draft" 로 생성되므로 release mutation 으로 별도 발행 필요.
7321
+ """
7322
+ materializeImportSession(input: MaterializeImportSessionInput!): Board!
6846
7323
  multipleUpload(files: [Upload!]!): [Attachment!]!
6847
7324
 
6848
7325
  """
@@ -6850,12 +7327,20 @@ type Mutation {
6850
7327
  """
6851
7328
  pickActivityInstance(id: String!): ActivityThread
6852
7329
 
7330
+ """프로젝트를 테넌트로 승격 (관리번호 발번 + project 카테고리 Domain 생성)"""
7331
+ promoteProjectToTenant(projectId: String!): Project!
7332
+
6853
7333
  """기존 KPI Value 인스턴스를 현재 formula/metric 값으로 재계산"""
6854
7334
  recalculateKpiValue(id: String!): KpiValue!
6855
7335
 
6856
7336
  """Recalculate scores for all KpiValues of a specific KPI"""
6857
7337
  recalculateScoresForKpi(kpiId: String!): Boolean!
6858
7338
 
7339
+ """
7340
+ Record a patch from user direct edit. Adds a system message so AI sees the change next turn.
7341
+ """
7342
+ recordDirectPatch(ops: JSON!, sessionId: String!, summary: String): PatchEntry!
7343
+
6859
7344
  """Record a metric value by metric name, value, meta, and org."""
6860
7345
  recordKpiMetricValue(
6861
7346
  """Extended or non-numeric information (JSON)."""
@@ -6907,10 +7392,16 @@ type Mutation {
6907
7392
 
6908
7393
  """Release a KPI and create a version history."""
6909
7394
  releaseKpi(id: String!): Kpi!
7395
+
7396
+ """Remove a user from the owners of the current domain."""
7397
+ removeDomainOwner(reason: String, username: String!): Boolean!
7398
+
7399
+ """Rename a ChatSession (tab label)."""
7400
+ renameChatSession(name: String!, sessionId: String!): Boolean!
6910
7401
  renewApplicationAccessToken(id: String!, scope: String!): AccessToken!
6911
7402
 
6912
- """Updates the sortOrder of a single board."""
6913
- reorderBoard(id: String!, sortOrder: Float!): Boolean!
7403
+ """Reorders a board between two adjacent boards by ID."""
7404
+ reorderBoard(id: String!, nextId: String, prevId: String): Boolean!
6914
7405
 
6915
7406
  """Sets the custom playback order for boards in a play group."""
6916
7407
  reorderPlayGroup(boardIds: [String!]!, id: String!): PlayGroup!
@@ -6932,6 +7423,9 @@ type Mutation {
6932
7423
  """Revert a KPI to a specific historical version."""
6933
7424
  revertKpiVersion(id: String!, version: Float!): Kpi!
6934
7425
 
7426
+ """Mark a patch as reverted (does not undo, only flags)."""
7427
+ revertPatch(patchId: String!): Boolean!
7428
+
6935
7429
  """
6936
7430
  Runs a new scenario instance once and returns the result after it finishes.
6937
7431
  """
@@ -6951,6 +7445,11 @@ type Mutation {
6951
7445
  """To start ActivityThread"""
6952
7446
  startActivityThread(id: String!, output: Object, reason: String): ActivityThread
6953
7447
 
7448
+ """
7449
+ Start (or get existing) AI chat session for a board. Idempotent — returns first existing or creates one.
7450
+ """
7451
+ startBoardAISession(boardId: String!): ChatSession!
7452
+
6954
7453
  """
6955
7454
  Starts automated data collection scheduling for the specified dataset. This mutation registers a cron-based schedule that automatically triggers data collection tasks according to the dataset configuration.
6956
7455
  """
@@ -7224,6 +7723,12 @@ type Mutation {
7224
7723
  """Updates multiple connections at once."""
7225
7724
  updateMultipleConnection(patches: [ConnectionPatch!]!): [Connection!]!
7226
7725
 
7726
+ """공종 기반 체크리스트 템플릿 생성/수정"""
7727
+ updateMultipleConstructionChecklistTemplate(patches: [ConstructionChecklistTemplatePatch!]!): [ConstructionChecklistTemplate!]!
7728
+
7729
+ """공종 체크리스트 템플릿 아이템 일괄 저장"""
7730
+ updateMultipleConstructionChecklistTemplateItems(constructionChecklistTemplateId: String!, patches: [ConstructionChecklistTemplateItemPatch!]!): [ConstructionChecklistTemplateItem!]!
7731
+
7227
7732
  """To modify multiple ConstructionDetailTypes' information"""
7228
7733
  updateMultipleConstructionDetailType(constructionTypeId: String!, patches: [ConstructionDetailTypePatch!]!): [ConstructionDetailType!]!
7229
7734
 
@@ -7419,6 +7924,9 @@ type Mutation {
7419
7924
  """프로젝트 업데이트 (중복 사용 금지)"""
7420
7925
  updateProject(project: ProjectPatch!): Project!
7421
7926
 
7927
+ """프로젝트 체크리스트 수정"""
7928
+ updateProjectChecklist(id: String!, items: [ProjectChecklistItemInput!]!, name: String!): ProjectChecklist!
7929
+
7422
7930
  """프로젝트 도면 업데이트"""
7423
7931
  updateProjectPlan(project: ProjectPatch!): Project!
7424
7932
 
@@ -7502,6 +8010,9 @@ type Mutation {
7502
8010
 
7503
8011
  """프로젝트 공정표 업로드"""
7504
8012
  uploadProjectScheduleTable(param: UploadProjectScheduleTable!): Boolean!
8013
+
8014
+ """공종+세부공종 조합으로 find-or-create"""
8015
+ upsertConstructionChecklistTemplate(constructionDetailTypeId: String!, constructionTypeId: String!): ConstructionChecklistTemplate!
7505
8016
  }
7506
8017
 
7507
8018
  input NewActionPlan {
@@ -8160,8 +8671,8 @@ input NewKpiMetric {
8160
8671
  """데이터 수집 방식"""
8161
8672
  collectType: KpiMetricCollectType
8162
8673
 
8163
- """ID of the source dataset for this metric."""
8164
- dataSetId: ID
8674
+ """Source dataset for this metric."""
8675
+ dataSet: ObjectRef
8165
8676
 
8166
8677
  """User-friendly name or description of the metric."""
8167
8678
  description: String
@@ -9310,6 +9821,26 @@ type PasswordRule {
9310
9821
  useTightPattern: Boolean
9311
9822
  }
9312
9823
 
9824
+ """One board edit operation history (cascade-deleted with ChatSession)."""
9825
+ type PatchEntry {
9826
+ """AI confidence 0..1 (null for user-direct)."""
9827
+ confidence: Float
9828
+ createdAt: DateTimeISO
9829
+ id: ID
9830
+
9831
+ """BoardEditOp[] (parsed JSON array)."""
9832
+ opsJson: JSON!
9833
+
9834
+ """Whether this patch was reverted."""
9835
+ reverted: Boolean!
9836
+
9837
+ """'ai' | 'user-direct' | 'import'"""
9838
+ source: String!
9839
+
9840
+ """Short human summary of this patch."""
9841
+ summary: String
9842
+ }
9843
+
9313
9844
  """Logs the request and response payloads for API interactions."""
9314
9845
  type PayloadLog {
9315
9846
  """The timestamp when the log entry was created."""
@@ -9575,6 +10106,7 @@ input ProfileInput {
9575
10106
  type Project {
9576
10107
  buildingComplex: BuildingComplex
9577
10108
  buildingUsage: String
10109
+ code: String
9578
10110
  completeReport: Attachment
9579
10111
  createdAt: DateTimeISO
9580
10112
  creator: User
@@ -9601,12 +10133,60 @@ type Project {
9601
10133
  state: String!
9602
10134
  structuralSafetyRate: Float
9603
10135
  tasks: [Task!]
10136
+
10137
+ """활성 테넌트 Domain (extType=project). 미승격 또는 강등 상태이면 null"""
10138
+ tenantDomain: Domain
9604
10139
  totalProgress: Float
9605
10140
  updatedAt: DateTimeISO
9606
10141
  updater: User
9607
10142
  weeklyProgress: Float
9608
10143
  }
9609
10144
 
10145
+ type ProjectChecklist {
10146
+ constructionDetailTypeId: String!
10147
+ constructionTypeId: String!
10148
+ createdAt: DateTimeISO
10149
+ creator: User
10150
+ deletedAt: DateTimeISO
10151
+ domain: Domain
10152
+ id: ID!
10153
+ name: String!
10154
+ projectChecklistItems: [ProjectChecklistItem!]
10155
+ projectId: String!
10156
+ updatedAt: DateTimeISO
10157
+ updater: User
10158
+ }
10159
+
10160
+ type ProjectChecklistItem {
10161
+ createdAt: DateTimeISO
10162
+ creator: User
10163
+ id: ID!
10164
+ inspctionCriteria: String
10165
+ mainType: String
10166
+ name: String!
10167
+ projectChecklist: ProjectChecklist
10168
+ sequence: Int
10169
+ updatedAt: DateTimeISO
10170
+ updater: User
10171
+ }
10172
+
10173
+ input ProjectChecklistItemInput {
10174
+ inspctionCriteria: String
10175
+ mainType: String
10176
+ name: String!
10177
+ sequence: Int
10178
+ }
10179
+
10180
+ type ProjectChecklistItemList {
10181
+ items: [ProjectChecklistItem!]!
10182
+ total: Int!
10183
+ }
10184
+
10185
+ type ProjectChecklistList {
10186
+ items: [ProjectChecklist!]!
10187
+ total: Int!
10188
+ }
10189
+
9610
10190
  type ProjectList {
9611
10191
  """프로젝트 리스트 항목들"""
9612
10192
  items: [Project!]!
@@ -10246,6 +10826,28 @@ type Query {
10246
10826
  """To fetch a building level"""
10247
10827
  buildingLevel(id: String!): BuildingLevel
10248
10828
 
10829
+ """List chat messages of a session, oldest first."""
10830
+ chatMessages(limit: Int = 100, offset: Int = 0, sessionId: String!): [ChatMessage!]!
10831
+
10832
+ """List patch entries of a session, newest first."""
10833
+ chatPatches(limit: Int = 100, sessionId: String!): [PatchEntry!]!
10834
+
10835
+ """Get AI chat session by id."""
10836
+ chatSession(id: String!): ChatSession
10837
+
10838
+ """
10839
+ Get AI chat session by board id (returns first match — backward compat single-session lookup).
10840
+ """
10841
+ chatSessionByBoard(boardId: String!): ChatSession
10842
+
10843
+ """List participants of a ChatSession (members / owner)."""
10844
+ chatSessionParticipants(sessionId: String!): [ChatSessionParticipant!]!
10845
+
10846
+ """
10847
+ List all AI chat sessions for a board (oldest first). Multi-session support — UI 탭으로 표시.
10848
+ """
10849
+ chatSessionsByBoard(boardId: String!): [ChatSession!]!
10850
+
10249
10851
  """
10250
10852
  Checks if the system is configured to provide a default password for new users.
10251
10853
  """
@@ -10473,6 +11075,36 @@ type Query {
10473
11075
  """Fetches a list of all available connector types."""
10474
11076
  connectors: ConnectorList!
10475
11077
 
11078
+ """공종 체크리스트 템플릿 아이템 목록"""
11079
+ constructionChecklistTemplateItems(
11080
+ """An array of filter conditions to apply to the list query."""
11081
+ filters: [Filter!]
11082
+
11083
+ """Inherited value type for the list query."""
11084
+ inherited: InheritedValueType
11085
+
11086
+ """Pagination options for the list query."""
11087
+ pagination: Pagination
11088
+
11089
+ """Sorting options for the list query."""
11090
+ sortings: [Sorting!]
11091
+ ): ConstructionChecklistTemplateItemList!
11092
+
11093
+ """공종 기반 체크리스트 템플릿 목록"""
11094
+ constructionChecklistTemplates(
11095
+ """An array of filter conditions to apply to the list query."""
11096
+ filters: [Filter!]
11097
+
11098
+ """Inherited value type for the list query."""
11099
+ inherited: InheritedValueType
11100
+
11101
+ """Pagination options for the list query."""
11102
+ pagination: Pagination
11103
+
11104
+ """Sorting options for the list query."""
11105
+ sortings: [Sorting!]
11106
+ ): ConstructionChecklistTemplateList!
11107
+
10476
11108
  """To fetch multiple ConstructionDetailTypes"""
10477
11109
  constructionDetailTypes(
10478
11110
  """An array of filter conditions to apply to the list query."""
@@ -10524,6 +11156,9 @@ type Query {
10524
11156
  sortings: [Sorting!]
10525
11157
  ): ContactList!
10526
11158
 
11159
+ """현재 테넌트 컨텍스트(extType=project)의 프로젝트. subdomain(=Project.code) 으로 조회."""
11160
+ currentProject: Project
11161
+
10527
11162
  """프로젝트 타입 조회"""
10528
11163
  currentProjectType: String!
10529
11164
  customers: [Domain!]!
@@ -10941,11 +11576,24 @@ type Query {
10941
11576
  sortings: [Sorting!]
10942
11577
  ): DomainLinkList!
10943
11578
 
11579
+ """List owners of the current domain."""
11580
+ domainOwners: [DomainOwner!]!
11581
+
10944
11582
  """
10945
11583
  Fetches the list of available domain types from configuration. Only superusers are granted this privilege.
10946
11584
  """
10947
11585
  domainTypes: [String!]!
10948
11586
 
11587
+ """
11588
+ List users in the current domain for `@` mention popup. board-ai 권한이면 누구나 멘션용 검색 가능 (관리자 전용 users() 와 별도).
11589
+ """
11590
+ domainUsersForMention(
11591
+ limit: Int = 50
11592
+
11593
+ """Substring to match against name/email (case-insensitive). Empty → all."""
11594
+ query: String
11595
+ ): [User!]!
11596
+
10949
11597
  """
10950
11598
  Fetches all domain entities with pagination and filtering options. Only superusers are granted this privilege.
10951
11599
  """
@@ -11166,6 +11814,12 @@ type Query {
11166
11814
  """To query whether I have the given permission"""
11167
11815
  hasPrivilege(category: String!, privilege: String!): Boolean!
11168
11816
 
11817
+ """Get import session progress."""
11818
+ importSession(id: String!): ImportSession
11819
+
11820
+ """List recent import sessions for a chat session."""
11821
+ importSessionsByChatSession(chatSessionId: String!): [ImportSession!]!
11822
+
11169
11823
  """BuildingInspection By ChecklistItemId"""
11170
11824
  inspectionByChecklistItemId: BuildingInspection!
11171
11825
 
@@ -11228,6 +11882,9 @@ type Query {
11228
11882
  invitation(email: EmailAddress!, reference: String!, type: String!): Invitation!
11229
11883
  invitations(reference: String!, type: String!): InvitationList!
11230
11884
 
11885
+ """Check if a user is an owner of the current domain."""
11886
+ isDomainOwner(username: String!): Boolean!
11887
+
11231
11888
  """To fetch a Issue"""
11232
11889
  issue(id: String!): Issue
11233
11890
 
@@ -11904,6 +12561,36 @@ type Query {
11904
12561
  """To fetch Project"""
11905
12562
  projectByBuildingLevelId(buildingLevelId: String!): Project!
11906
12563
 
12564
+ """프로젝트 체크리스트 아이템 목록"""
12565
+ projectChecklistItems(
12566
+ """An array of filter conditions to apply to the list query."""
12567
+ filters: [Filter!]
12568
+
12569
+ """Inherited value type for the list query."""
12570
+ inherited: InheritedValueType
12571
+
12572
+ """Pagination options for the list query."""
12573
+ pagination: Pagination
12574
+
12575
+ """Sorting options for the list query."""
12576
+ sortings: [Sorting!]
12577
+ ): ProjectChecklistItemList!
12578
+
12579
+ """프로젝트 체크리스트 목록"""
12580
+ projectChecklists(
12581
+ """An array of filter conditions to apply to the list query."""
12582
+ filters: [Filter!]
12583
+
12584
+ """Inherited value type for the list query."""
12585
+ inherited: InheritedValueType
12586
+
12587
+ """Pagination options for the list query."""
12588
+ pagination: Pagination
12589
+
12590
+ """Sorting options for the list query."""
12591
+ sortings: [Sorting!]
12592
+ ): ProjectChecklistList!
12593
+
11907
12594
  """To fetch a ProjectReport"""
11908
12595
  projectReport(id: String!): ProjectReport
11909
12596
 
@@ -12114,6 +12801,14 @@ type Query {
12114
12801
  sortings: [Sorting!]
12115
12802
  ): StepList!
12116
12803
 
12804
+ """
12805
+ 도메인 안에서 충돌하지 않는 Board name + 상세 description 제안. name 은 짧고 심플 (30자 이내, 충돌 회피 (n) suffix), description 은 자세히 (사용자 prompt + AI importStrategy + 카테고리 분포 통계 합성).
12806
+ """
12807
+ suggestBoardMeta(input: SuggestBoardNameInput!): BoardMetaSuggestion!
12808
+
12809
+ """@deprecated suggestBoardMeta 사용 권장. 단순 string name 만 반환하는 구버전 query."""
12810
+ suggestBoardName(input: SuggestBoardNameInput!): String!
12811
+
12117
12812
  """To fetch the list of activities that I can report on"""
12118
12813
  supervisableActivities(
12119
12814
  """An array of filter conditions to apply to the list query."""
@@ -13060,6 +13755,16 @@ type Subscription {
13060
13755
  scenarioQueueState: ScenarioQueueState!
13061
13756
  }
13062
13757
 
13758
+ input SuggestBoardNameInput {
13759
+ """명시 hint. session 정보보다 우선. 사용자가 직접 적은 메모를 기반으로 추천받고 싶을 때."""
13760
+ hint: String
13761
+
13762
+ """
13763
+ ImportSession id — 있으면 거기서 userPrompt / VLM reasoning / attachment.name 추출.
13764
+ """
13765
+ sessionId: ID
13766
+ }
13767
+
13063
13768
  """Entity for Supervisor"""
13064
13769
  type Supervisor {
13065
13770
  active: Boolean
@@ -13361,6 +14066,21 @@ input ThemePatch {
13361
14066
  value: Object
13362
14067
  }
13363
14068
 
14069
+ """썸네일 백필 결과"""
14070
+ type ThumbnailBackfillResult {
14071
+ """이번 호출에서 처리 시도한 첨부 개수"""
14072
+ attempted: Int!
14073
+
14074
+ """실패(생성 실패/콘텐츠 없음 등) 개수"""
14075
+ failed: Int!
14076
+
14077
+ """이번 처리 후에도 남아있는 썸네일 미생성 후보 개수 (대략치). 0 이면 완료"""
14078
+ remaining: Int!
14079
+
14080
+ """썸네일 생성·저장 성공 개수"""
14081
+ succeeded: Int!
14082
+ }
14083
+
13364
14084
  input UpdateBuildingInspection {
13365
14085
  drawingMarker: String
13366
14086
  id: String!
@@ -13372,6 +14092,7 @@ input UpdateBuildingInspectionSubmitType {
13372
14092
  checklistItem: [ChecklistItemSubmitInputType!]!
13373
14093
  id: String!
13374
14094
  memo: String
14095
+ requestDate: String
13375
14096
  }
13376
14097
 
13377
14098
  input UpdateTaskChecklistSubmitType {