@things-factory/figure-service 10.1.15 → 10.1.16
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.
- package/dist-server/service/figure/figure-query.d.ts +12 -2
- package/dist-server/service/figure/figure-query.js +18 -2
- package/dist-server/service/figure/figure-query.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/server/service/figure/figure-blueprint-query.test.ts +29 -0
- package/server/service/figure/figure-query.ts +18 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/figure-service",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.16",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"@things-factory:registry": "https://registry.npmjs.org"
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"@hatiolab/figure-model": "^0.1.17",
|
|
27
27
|
"@operato/typeorm-history": "^10.0.0",
|
|
28
28
|
"@things-factory/ai-client-base": "^10.1.8",
|
|
29
|
-
"@things-factory/auth-base": "^10.1.
|
|
29
|
+
"@things-factory/auth-base": "^10.1.16",
|
|
30
30
|
"@things-factory/env": "^10.1.3",
|
|
31
|
-
"@things-factory/shell": "^10.1.
|
|
31
|
+
"@things-factory/shell": "^10.1.16",
|
|
32
32
|
"graphql-scalars": "^1.22.4",
|
|
33
33
|
"graphql-upload": "^15.0.2",
|
|
34
34
|
"koa-router": "^7.4.0"
|
|
35
35
|
},
|
|
36
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "aff86bc162b42c1d933711f7bc85a073f1ddcd29"
|
|
37
37
|
}
|
|
@@ -175,4 +175,33 @@ describe('figureBlueprint 질의 — 소비처(board, twin, things-scene)를 위
|
|
|
175
175
|
expect(result.groups[0].members[0].name).toBe('box-1')
|
|
176
176
|
expect(result.groups[0].members[0].transform.size.x).toBe(100)
|
|
177
177
|
})
|
|
178
|
+
|
|
179
|
+
/*
|
|
180
|
+
Every test above calls the resolver method directly, so none of them passes through the
|
|
181
|
+
`@privilege` directive — that is attached when the schema is assembled. They stay green
|
|
182
|
+
whether the declaration is there or not.
|
|
183
|
+
|
|
184
|
+
Without a declaration this field is open to callers who have not even signed in
|
|
185
|
+
(`auth-rebuild.md` §1), so that gap is the thing worth guarding. The check reads the source
|
|
186
|
+
rather than the compiled output because the declaration is authored there, and it pins the
|
|
187
|
+
category: `figure` is the authoring permission, and requiring it here would leave board and
|
|
188
|
+
twin users with an empty palette. Someone who hits that wall will be tempted to delete this
|
|
189
|
+
line; the failure message is for them.
|
|
190
|
+
*/
|
|
191
|
+
it('declares figure-published on the consumer door, not the authoring permission', () => {
|
|
192
|
+
const { readFileSync } = require('fs')
|
|
193
|
+
const { join } = require('path')
|
|
194
|
+
const source = readFileSync(join(__dirname, 'figure-query.ts'), 'utf-8')
|
|
195
|
+
|
|
196
|
+
const at = source.indexOf('async figureBlueprint')
|
|
197
|
+
expect(at).toBeGreaterThan(-1)
|
|
198
|
+
|
|
199
|
+
const preceding = source.slice(0, at)
|
|
200
|
+
const directive = preceding.lastIndexOf("@Directive('@privilege(")
|
|
201
|
+
const declaration = preceding.slice(directive, preceding.indexOf('\n', directive))
|
|
202
|
+
|
|
203
|
+
expect(declaration).toContain('category: "figure-published"')
|
|
204
|
+
expect(declaration).toContain('privilege: "query"')
|
|
205
|
+
expect(declaration).toContain('domainOwnerGranted: true')
|
|
206
|
+
})
|
|
178
207
|
})
|
|
@@ -140,9 +140,25 @@ export class FigureQuery {
|
|
|
140
140
|
* 4. 한 번도 발행된 적 없는 초안 자산이거나 존재하지 않는 타입인 경우 null을 반환하여
|
|
141
141
|
* 미완성 자산이 씬 화면에 유출되는 것을 엄격히 차단한다.
|
|
142
142
|
* 5. 도메인 상속 시 자식 도메인의 타입이 부모 도메인의 동일 타입을 항상 오버라이드한다.
|
|
143
|
-
* 6.
|
|
144
|
-
*
|
|
143
|
+
* 6. 권한은 저작(`figure`)과 **다른 category** 인 `figure-published` 다. 소비처 사용자에게
|
|
144
|
+
* 저작 권한을 요구하면 board·twin 의 팔레트가 안 뜨고, 그렇다고 선언을 비우면 이 집에서는
|
|
145
|
+
* 로그인조차 안 한 사람에게 열린다(`auth-rebuild.md` §1). `<module>-published` 는
|
|
146
|
+
* 「그 모듈이 발행한 것을 남이 읽는 문」이라는 규약이다 — 아키텍트 판정(2026-09-15).
|
|
147
|
+
*
|
|
148
|
+
* ## 열거는 막혀 있다 — 지금은 우연이다
|
|
149
|
+
*
|
|
150
|
+
* 이 문의 열쇠는 `type` 하나뿐이라 이름을 모르면 못 꺼낸다. 그런데 그것이 **설계가 아니다** —
|
|
151
|
+
* 목록을 내는 `figures`·`figureTypeNames` 가 `figure` category 로 잠겨 있어서 결과적으로
|
|
152
|
+
* 그런 것뿐이다. 나중에 누가 소비처용 목록 문을 하나 더 열고 `figure-published` 를 붙이면
|
|
153
|
+
* 열거가 함께 열리고, 「이름을 알아야 한다」에 기대고 있던 가정이 조용히 사라진다.
|
|
154
|
+
* 그 문을 낼 사람이 이 단락을 읽고 그때 정하면 된다.
|
|
145
155
|
*/
|
|
156
|
+
/*
|
|
157
|
+
This directive is attached by schema assembly, so a test that calls the resolver method
|
|
158
|
+
directly never exercises it. `figure-blueprint-query.test.ts` reads this source for the
|
|
159
|
+
declaration instead — see the test named for it there.
|
|
160
|
+
*/
|
|
161
|
+
@Directive('@privilege(category: "figure-published", privilege: "query", domainOwnerGranted: true)')
|
|
146
162
|
@Query(returns => GraphQLJSON, {
|
|
147
163
|
nullable: true,
|
|
148
164
|
description: 'Compiled FigureBlueprint for external consumers (board, twin, things-scene). Only returns released figures.'
|