@joymerrevent/porters-connect 0.9.0 → 0.11.0
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/CHANGELOG.md +153 -1
- package/README.md +43 -39
- package/dist/index.d.ts +448 -60
- package/dist/index.js +247 -133
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,150 @@
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.11.0] - 2026-08-30
|
|
9
|
+
|
|
10
|
+
**参照先の項目を 1 往復で読めるようにし、`field` の語彙をクエリ全体と揃えた版**です。
|
|
11
|
+
どちらも「**要求したものが黙って返らない**」を潰す変更で、`field` に接頭辞を書かなくなる
|
|
12
|
+
**破壊的変更**を含みます(移行は接頭辞を消すだけ)。
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **参照型の展開 `expand`**([ADR-0058][adr58])。`System[Reference]` の項目(`Job.P_Client` など)から
|
|
17
|
+
**参照先の項目そのもの**を取得できるようになりました。これまでは参照先の **ID だけ**を取り出し、
|
|
18
|
+
入れ子で返ってきた残りを**黙って捨てて**いました。
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
const page = await t.job.search({ expand: { P_Client: ["P_Id", "P_Name"] } });
|
|
22
|
+
page.items[0]?.P_Client; // { P_Id: number | null; P_Name: string | null } | null
|
|
23
|
+
|
|
24
|
+
const plain = await t.job.search();
|
|
25
|
+
plain.items[0]?.P_Client; // number | null(従来どおり)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- **参照先の接頭辞は書きません**。`condition` / `order` / `field` と同じ素の alias で指定すると、
|
|
29
|
+
ライブラリが `field=Job.P_Client(Client.P_Id,Client.P_Name)` を組み立てます。
|
|
30
|
+
Candidate を参照するときの `Person.` も同様です。
|
|
31
|
+
- **`expand` を書いた項目だけ**戻り型が変わります。基底の型は `number | null` のままなので、
|
|
32
|
+
**参照を ID として使っているコードは無変更**です。展開しなかった参照も ID のまま返ります。
|
|
33
|
+
- `search` / `searchAll` / `get(id, { expand })` で使えます。`get` は第 2 引数が増えただけで、
|
|
34
|
+
既存の `get(id)` はそのままです。
|
|
35
|
+
- 展開した alias は**素のエントリを置き換えて**送られます。同じ alias を `()` 有り・無しで 2 回送ったとき
|
|
36
|
+
どちらが優先されるかは PORTERS のドキュメントに記述が無いため、**そもそも送りません**。
|
|
37
|
+
- 展開できるのは**参照先をライブラリが実装している項目**だけです。`P_Recruiter`(Recruiter は未実装)と
|
|
38
|
+
カスタム項目(`U_`/`A_`)の参照型は対象外で、**従来どおり ID として読めます**。書くと型エラーです。
|
|
39
|
+
- `field` に `"Job.P_Client(Client.P_Id)"` のような展開文字列を書くと、送信前に
|
|
40
|
+
`PortersConfigError` で止まり `expand` を案内します。
|
|
41
|
+
- `()` の中に付ける参照先の接頭辞と入れ子の形は**実機で未確認**です
|
|
42
|
+
([live-verification][lv] LV-10 / LV-16)。応答の解釈はタグ名に依存しない実装です。
|
|
43
|
+
|
|
44
|
+
- **型の export**: `Expand` / `ExpandedReadRecord` / `ReferenceMap` / `ResourcePageOf` /
|
|
45
|
+
`ReferenceRecord` / `ReadFieldAlias`。`FieldValue` に `ReferenceRecord`(展開された参照の値)が加わります。
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
- **(破壊的)Read の `field` は接頭辞なしの alias で書きます**([ADR-0059][adr59])。
|
|
50
|
+
接頭辞はリソースごとの定数なので、**ライブラリが付けます**。
|
|
51
|
+
|
|
52
|
+
```diff
|
|
53
|
+
- field: ["Person.P_Id", "Person.P_Name"]
|
|
54
|
+
+ field: ["P_Id", "P_Name"]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- 移行は**接頭辞を消すだけ**です。送られる URL は従来と同じで、変わるのは書き方と、
|
|
58
|
+
**どこで間違いに気づけるか**だけです。
|
|
59
|
+
- `condition` / `order` / `expand` はもともと素の alias を受けていたため、
|
|
60
|
+
**同じクエリの中で語彙が 2 つあった**状態が解消されます。
|
|
61
|
+
- **間違いがコンパイルエラーになります** — 綴り間違い(`P_Nmae`)・接頭辞付き(`Person.P_Name`)・
|
|
62
|
+
リソース名との取り違え(`Candidate.P_Name`。Candidate の接頭辞は `Person` です)・展開文字列。
|
|
63
|
+
これまでは型(`string[]`)でも送信前ガードでも素通りし、**PORTERS 側で黙って無視される**だけでした。
|
|
64
|
+
- **未宣言のカスタム項目は引き続き書けます**(`U_` / `A_` で始まる名前)。ただし `U_` 以降の綴りは
|
|
65
|
+
検査できないので、よく使うものは `defineFields` で宣言してください(宣言すれば綴りも検査されます)。
|
|
66
|
+
- 実行時は接頭辞付きが来ても**剥がして受けます**(応答側と対称の寛容さ)。cast 経由の古い形も壊れません。
|
|
67
|
+
- 対象は `SearchQuery.field`(データ 5 リソース)と `UserSearchQuery.field`(マスタ User)。
|
|
68
|
+
**Attachment は元から接頭辞なし**なので変更ありません。`field: []`(主キーのみ)と
|
|
69
|
+
省略時の既定 field([ADR-0020][adr20])の意味も変わりません。
|
|
70
|
+
- **pre-1.0 のため minor**([ADR-0055][adr55] と同じ扱い)。
|
|
71
|
+
|
|
72
|
+
- **明示した `field` も既定 field と同じ組み立てを通る**ようになりました。`User` 型の項目を
|
|
73
|
+
`field` で明示すると **4 サブ項目に展開**されます(`Job.P_Owner(User.P_Id,User.P_Type,User.P_Name,User.P_Mail)`)。
|
|
74
|
+
これまでは `()` 無しで送られ、PORTERS が ID を返すため、**型が `UserRef` を約束するのに実体は `null`**
|
|
75
|
+
になっていました。
|
|
76
|
+
|
|
77
|
+
### Fixed
|
|
78
|
+
|
|
79
|
+
- **参照 ID の読み取りが、リソース名と alias 接頭辞の食い違いで `null` に落ちていました**。
|
|
80
|
+
入れ子の**包みタグはリソース名**なのに**中の alias は接頭辞付き**で、この 2 つが異なる Candidate
|
|
81
|
+
(`<Candidate>` に `Person.P_Id`)では従来の照合が外れていました。**素の alias で照合**するようにしたので、
|
|
82
|
+
どちらの表記でも読めます。
|
|
83
|
+
- 影響していたのは `Process.P_Candidate` / `Resume.P_Candidate`(Candidate を参照する項目)です。
|
|
84
|
+
包みタグの実際の値は**実機で未確認**([live-verification][lv] LV-10)で、フェイクサーバーは
|
|
85
|
+
これまで中立な包みを返していたため、テストでは露出していませんでした。
|
|
86
|
+
|
|
87
|
+
## [0.10.0] - 2026-08-22
|
|
88
|
+
|
|
89
|
+
**partition の束ね方を 1 つに絞り、削除済みレコードを判別できるようにした版**です。
|
|
90
|
+
`PortersClient` から `partition` を外した**破壊的変更**を含みます(移行は下記)。
|
|
91
|
+
併せて、削除済みを読めるのに**どれが削除済みか分からなかった**穴を塞ぎました。
|
|
92
|
+
|
|
93
|
+
### Added
|
|
94
|
+
|
|
95
|
+
- **削除フラグ `P_Deleted`**([ADR-0056][adr56])。データ系 5 リソース(Candidate / Job / Client /
|
|
96
|
+
Process / Resume)の公開型に加わり、`itemstate: "all"` の結果から削除済みを**判別できる**ようになりました。
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
const page = await t.candidate.search({ itemstate: "all" });
|
|
100
|
+
const deleted = page.items.filter((c) => c.P_Deleted === "1");
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
- **値は文字列**の `"0"`(生存)/`"1"`(削除済み)です。`number` でも `boolean` でもありません。
|
|
104
|
+
PORTERS がこの項目に **Data Type を与えていない**(reference の Field Type / Data Type 欄がともに「ー」)ため、
|
|
105
|
+
変換の基準がありません。勝手に決めればライブラリの発明になるので、**生の値のまま**返します。
|
|
106
|
+
- **`condition` にも `order` にも指定できず、Write もできません**(PORTERS の制約)。
|
|
107
|
+
いずれも型で表現されているので、書くとコンパイルエラーになります。
|
|
108
|
+
- `field` を省略すれば**自動で要求**されます。自分で `field` を渡すときは
|
|
109
|
+
`"Person.P_Deleted"` のように接頭辞付きで明示してください。
|
|
110
|
+
- 削除 API が無い PORTERS では「削除済みを読む」こと自体が運用手段(同期・監査・復元の判断材料)ですが、
|
|
111
|
+
これまでは**読めるのに解釈できない**状態でした。
|
|
112
|
+
- 応答での出現条件と値域は**実機で未確認**です([live-verification][lv] LV-14)。
|
|
113
|
+
|
|
114
|
+
### Changed
|
|
115
|
+
|
|
116
|
+
- **(破壊的)`PortersClient` から `partition` を外しました**([ADR-0055][adr55])。
|
|
117
|
+
partition(Company DB)スコープのリソースは **`porters.tenant(id)` 経由でのみ**取得します。
|
|
118
|
+
**単一テナントでも同じ形**です。
|
|
119
|
+
|
|
120
|
+
```diff
|
|
121
|
+
- const porters = new PortersClient({ host, appId, appSecret, partition: 123 });
|
|
122
|
+
- await porters.candidate.search();
|
|
123
|
+
+ const porters = new PortersClient({ host, appId, appSecret });
|
|
124
|
+
+ const t = porters.tenant(123);
|
|
125
|
+
+ await t.candidate.search();
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
- 影響するのは `candidate` / `job` / `client` / `process` / `resume` / `attachment` /
|
|
129
|
+
`user` / `field` / `option` の 9 アクセサ。`t` は以降クライアントのように使えるので、
|
|
130
|
+
**呼び出し側の書き味は変わりません**。
|
|
131
|
+
- **App レベルのものは `porters` 側に残ります**(いずれも `partition` を取りません)—
|
|
132
|
+
`porters.auth.*`(OAuth)と `porters.partition.search()`(partition の発見)。
|
|
133
|
+
- 理由: `partition` 未設定のクライアントは**`partition=0`** を全リクエストに載せていました。
|
|
134
|
+
`0` は PORTERS のドキュメントに存在しない値で、由来は最初の PoC の穴埋めです。実際には
|
|
135
|
+
Result Code **404** を招くため、**設定漏れが「サーバーが 404 を返す」形に化け**ていました。
|
|
136
|
+
`tenant(id)` を唯一の経路にすることで、**「partition を束ね忘れたクライアント」という状態が
|
|
137
|
+
型として存在しなくなります**。実行時ガードを足すのではなく、設計で防ぐ形にしました。
|
|
138
|
+
- **pre-1.0 のため minor**。誤った partition を渡すこと自体は妨げません(404 はサーバーが答えます)。
|
|
139
|
+
|
|
140
|
+
### Fixed
|
|
141
|
+
|
|
142
|
+
- **`itemstate: "existing"` を明示指定したとき、省略せずそのまま送る**ようになりました
|
|
143
|
+
([ADR-0057][adr57])。**返るデータは変わりません** — 変わるのは送信 URL だけです。
|
|
144
|
+
- これまでは `existing` が API の既定であることを理由に、明示指定でも param を省いていました。
|
|
145
|
+
しかし**省略(「既定に委ねる」)と明示(「生存レコードのみが欲しい」)は別の意思表示**です。
|
|
146
|
+
いま結果が同じなのは PORTERS の既定が `existing` だからで、**もし将来この既定が変われば、
|
|
147
|
+
生存のみを求めたコードに削除済みが混ざり始めます**(例外も Result Code も出ないので気づけません)。
|
|
148
|
+
- 生存のみであることが業務上重要なら、省略せず `itemstate: "existing"` と書いてください。
|
|
149
|
+
省略した場合はこれまでどおり API の既定に従います。
|
|
150
|
+
- `itemstate=existing` の実機送信実績はまだありません([live-verification][lv] LV-15)。
|
|
151
|
+
|
|
8
152
|
## [0.9.0] - 2026-08-20
|
|
9
153
|
|
|
10
154
|
**Candidate でメモ・住所詳細が扱えるようになった版**です。標準項目でありながらカタログから漏れていた
|
|
@@ -288,9 +432,17 @@
|
|
|
288
432
|
[adr35]: docs/adr/0035-usage-documentation-structure.md
|
|
289
433
|
[custom-fields-guide]: docs/guide/custom-fields.md
|
|
290
434
|
[read-query-guide]: docs/guide/read-query.md
|
|
435
|
+
[adr55]: docs/adr/0055-partition-binding-guard.md
|
|
436
|
+
[adr56]: docs/adr/0056-deleted-flag-typing.md
|
|
437
|
+
[adr57]: docs/adr/0057-itemstate-existing-explicit.md
|
|
438
|
+
[adr58]: docs/adr/0058-reference-expansion-read.md
|
|
439
|
+
[adr59]: docs/adr/0059-read-field-bare-alias.md
|
|
440
|
+
[lv]: docs/live-verification.md
|
|
291
441
|
[kac]: https://keepachangelog.com/en/1.1.0/
|
|
292
442
|
[semver]: https://semver.org/
|
|
293
|
-
[unreleased]: https://github.com/Joymerrevent/porters-connect/compare/v0.
|
|
443
|
+
[unreleased]: https://github.com/Joymerrevent/porters-connect/compare/v0.11.0...HEAD
|
|
444
|
+
[0.11.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.10.0...v0.11.0
|
|
445
|
+
[0.10.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.9.0...v0.10.0
|
|
294
446
|
[0.9.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.8.0...v0.9.0
|
|
295
447
|
[0.8.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.7.0...v0.8.0
|
|
296
448
|
[0.7.0]: https://github.com/Joymerrevent/porters-connect/compare/v0.6.2...v0.7.0
|
package/README.md
CHANGED
|
@@ -58,15 +58,14 @@ const porters = new PortersClient({
|
|
|
58
58
|
scheme: process.env.PORTERS_SCHEME === "http" ? "http" : undefined,
|
|
59
59
|
appId: process.env.PORTERS_APP_ID!,
|
|
60
60
|
appSecret: process.env.PORTERS_APP_SECRET!,
|
|
61
|
-
partition: 123, // 既定 Partition(Company DB)Id
|
|
62
61
|
});
|
|
63
62
|
|
|
64
|
-
//
|
|
63
|
+
// partition(Company DB)は tenant で一度だけ束ねる。**単一テナントでもこの形**
|
|
64
|
+
// 以降は `t` をクライアントのように使う(client 直下には auth と partition マスタだけ)
|
|
65
65
|
const t = porters.tenant(456);
|
|
66
|
-
await t.candidate.search({ condition: { P_Name: { part: "鈴木" } } }); // partition=456
|
|
67
66
|
|
|
68
67
|
// 検索(最大 200 件/ページ)。condition は項目の Data Type ごとに型付き
|
|
69
|
-
const page = await
|
|
68
|
+
const page = await t.candidate.search({
|
|
70
69
|
condition: { P_Name: { part: "山田" } }, // テキストは part(部分一致)/ full(完全一致)
|
|
71
70
|
order: [{ P_UpdateDate: "desc" }], // 並び順(数値・日時・System のみ)
|
|
72
71
|
count: 50,
|
|
@@ -74,18 +73,21 @@ const page = await porters.candidate.search({
|
|
|
74
73
|
console.log(page.total, page.items.length);
|
|
75
74
|
|
|
76
75
|
// 1 件取得
|
|
77
|
-
const one = await
|
|
76
|
+
const one = await t.candidate.get(10001);
|
|
78
77
|
console.log(one?.P_Name);
|
|
79
78
|
|
|
80
79
|
// 全件を自動ページング(200 件刻み)
|
|
81
|
-
for await (const c of
|
|
80
|
+
for await (const c of t.candidate.searchAll({
|
|
82
81
|
condition: { P_Prefecture: { full: "東京都" } },
|
|
83
82
|
})) {
|
|
84
83
|
// c は 1 件ずつ
|
|
85
84
|
}
|
|
86
85
|
```
|
|
87
86
|
|
|
88
|
-
>
|
|
87
|
+
> **`partition` はクライアントに持たせません**(ADR-0055)。PORTERS は partition スコープの全リクエストで
|
|
88
|
+
> `partition` を要求するので、`tenant(id)` で**明示的に一度だけ**束ねる形にしています。
|
|
89
|
+
> 複数 partition を 1 つの App で扱う場合・テナント別 client・partition の発見は
|
|
90
|
+
> [マルチテナント ガイド][multi-tenancy] にまとめています。
|
|
89
91
|
>
|
|
90
92
|
> 認証情報やホスト名は**コミットしない**でください。`.env.example` を参考に `.env` で渡します。
|
|
91
93
|
|
|
@@ -103,7 +105,6 @@ const porters = new PortersClient({
|
|
|
103
105
|
host: "sandbox.invalid",
|
|
104
106
|
appId: "demo",
|
|
105
107
|
appSecret: "demo",
|
|
106
|
-
partition: 1,
|
|
107
108
|
transport: createMockTransport((req) =>
|
|
108
109
|
req.url.includes("/v1/candidate")
|
|
109
110
|
? `<Candidate Total="1" Count="1" Start="0"><Code>0</Code><Item><Person.P_Id>1</Person.P_Id><Person.P_Name>山田 太郎</Person.P_Name></Item></Candidate>`
|
|
@@ -111,7 +112,7 @@ const porters = new PortersClient({
|
|
|
111
112
|
), // 未モックのリクエストは明示エラー(フェイルセーフ)
|
|
112
113
|
});
|
|
113
114
|
|
|
114
|
-
const page = await
|
|
115
|
+
const page = await t.candidate.search();
|
|
115
116
|
console.log(page.items[0]?.P_Name); // 山田 太郎
|
|
116
117
|
```
|
|
117
118
|
|
|
@@ -141,7 +142,7 @@ const tokenStore: TokenStore = {
|
|
|
141
142
|
/* 破棄 */
|
|
142
143
|
},
|
|
143
144
|
};
|
|
144
|
-
new PortersClient({ host, appId, appSecret,
|
|
145
|
+
new PortersClient({ host, appId, appSecret, tokenStore });
|
|
145
146
|
```
|
|
146
147
|
|
|
147
148
|
`transport`(HTTP 注入)や `auth`(独自 `TokenProvider`)も差し替え可能です。
|
|
@@ -166,26 +167,29 @@ await porters.auth.exchangeAuthorizationCode(code);
|
|
|
166
167
|
|
|
167
168
|
すべてのデータ系リソースは同じ形のアクセサを持ちます。
|
|
168
169
|
|
|
169
|
-
| アクセサ
|
|
170
|
-
|
|
|
171
|
-
| `
|
|
172
|
-
| `
|
|
173
|
-
| `
|
|
174
|
-
| `
|
|
175
|
-
| `
|
|
176
|
-
| `
|
|
170
|
+
| アクセサ | リソース | メソッド |
|
|
171
|
+
| -------------- | ------------ | ---------------------------------------------------- |
|
|
172
|
+
| `t.candidate` | 個人連絡先 | `search` / `searchAll` / `get` / `create` / `update` |
|
|
173
|
+
| `t.job` | JOB | `search` / `searchAll` / `get` / `create` / `update` |
|
|
174
|
+
| `t.client` | 企業 | `search` / `searchAll` / `get` / `create` / `update` |
|
|
175
|
+
| `t.process` | 選考プロセス | `search` / `searchAll` / `get` / `create` / `update` |
|
|
176
|
+
| `t.resume` | レジュメ | `search` / `searchAll` / `get` / `create` / `update` |
|
|
177
|
+
| `t.attachment` | 添付ファイル | `search` / `get` / `create` / `update` |
|
|
177
178
|
|
|
178
179
|
- `search(query?)` → `{ items, total, count, start }`(オフセット式ページング)。
|
|
179
180
|
- `searchAll(query?)` → `AsyncIterable`(200 件刻みで全件 yield)。
|
|
180
|
-
- `get(id)` → 1 件 or `undefined
|
|
181
|
+
- `get(id, options?)` → 1 件 or `undefined`(`options.expand` で参照先の項目も読めます)。
|
|
181
182
|
- `create(input)` → 採番された **id(number)**。
|
|
182
183
|
- `update(id, input)` → その **id**。
|
|
183
184
|
|
|
184
185
|
**検索クエリ**(`query`)の主なキー(すべて型安全。**項目の Data Type が許す演算子だけ**を受けます):
|
|
185
186
|
|
|
186
|
-
- `field
|
|
187
|
+
- `field`:取得する項目(**接頭辞なし**の alias の配列。例 `["P_Id", "P_Name"]`。接頭辞はライブラリが付けます)。
|
|
188
|
+
綴り間違いや接頭辞付きは**コンパイルエラー**になります。
|
|
187
189
|
**省略するとカタログ上の全項目を既定取得**します(PORTERS は field 未指定だと主キーのみ返すため、
|
|
188
190
|
ライブラリが既定 field を補います)。`field: []`(空配列)を渡すと API 仕様どおり**主キーのみ**を返します(件数取得など)。
|
|
191
|
+
- `expand`:参照型(`System[Reference]`)の項目について、**参照先の項目も読む**(`{ P_Client: ["P_Id", "P_Name"] }`)。
|
|
192
|
+
書かなければ従来どおり**参照先の ID**が返り、**書いた項目だけ**戻り型が参照レコードに変わります。1 往復で済みます。
|
|
189
193
|
- `condition`:検索条件。`{ 項目: { 演算子: 値 } }` 形式(複数項目は AND)。演算子は Data Type ごとに
|
|
190
194
|
`eq`/`gt`/`ge`/`le`/`lt`(数値・日時・Id)、`part`/`full`(テキスト)、`or`/`and`(Option・参照/ユーザー型は ID)。
|
|
191
195
|
**日時の値は ISO 8601(UTC `…Z`)**で渡すと PORTERS 形式へ自動変換します。
|
|
@@ -197,8 +201,9 @@ await porters.auth.exchangeAuthorizationCode(code);
|
|
|
197
201
|
> **削除 API はありません**(PORTERS 仕様)。`delete()` メソッドは提供しません。削除済みは `itemstate: "deleted"` で読みます
|
|
198
202
|
> (`condition` は `P_Id` / `P_UpdateDate` / `P_UpdatedBy` に限られ、更新日は 90 日以内)。
|
|
199
203
|
>
|
|
200
|
-
> `field` の 3 通りの意味(省略=全項目 / `[]`=主キーのみ /
|
|
201
|
-
>
|
|
204
|
+
> `field` の 3 通りの意味(省略=全項目 / `[]`=主キーのみ / 明示)、`expand` で展開できる項目、
|
|
205
|
+
> Data Type ごとの演算子一覧、削除済み Read の制約、送信前に落ちる条件は
|
|
206
|
+
> [Read クエリ ガイド][read-query-guide] にまとめています。
|
|
202
207
|
|
|
203
208
|
### カスタム項目(`U_` / `A_`)
|
|
204
209
|
|
|
@@ -214,11 +219,10 @@ const porters = new PortersClient({
|
|
|
214
219
|
host,
|
|
215
220
|
appId,
|
|
216
221
|
appSecret,
|
|
217
|
-
partition,
|
|
218
222
|
fields,
|
|
219
223
|
});
|
|
220
224
|
|
|
221
|
-
const one = await
|
|
225
|
+
const one = await t.candidate.get(10001);
|
|
222
226
|
one?.U_score; // number | null | undefined
|
|
223
227
|
```
|
|
224
228
|
|
|
@@ -234,25 +238,25 @@ one?.U_score; // number | null | undefined
|
|
|
234
238
|
| アクセサ | リソース | メソッド | 主なクエリ |
|
|
235
239
|
| ------------------- | ----------------- | ---------------------------------- | ----------------------------------------- |
|
|
236
240
|
| `porters.partition` | Partition | `search` / `searchAll` | `requestType`(1=アクセス可能一覧・既定) |
|
|
237
|
-
| `
|
|
238
|
-
| `
|
|
239
|
-
| `
|
|
241
|
+
| `t.user` | User | `search` / `searchAll` / `current` | `requestType` / `userType` / `field` |
|
|
242
|
+
| `t.field` | Field(項目定義) | `search` / `searchAll` | `resource`(必須)/ `active` |
|
|
243
|
+
| `t.option` | Option(選択肢) | `search` | `alias` / `level` / `enabled` |
|
|
240
244
|
|
|
241
245
|
```ts
|
|
242
246
|
// アクセス可能な Partition(Company DB)を発見
|
|
243
247
|
const partitions = await porters.partition.search();
|
|
244
248
|
|
|
245
249
|
// 現在の API ユーザー(code_direct ではアプリ自身の User)=自己同定
|
|
246
|
-
const me = await
|
|
250
|
+
const me = await t.user.current();
|
|
247
251
|
|
|
248
252
|
// Job リソースの項目定義(U_/A_ カスタム項目を含む)を取得
|
|
249
|
-
const fields = await
|
|
253
|
+
const fields = await t.field.search({ resource: "job" });
|
|
250
254
|
|
|
251
255
|
// 選択肢マスタをフラットな配列で取得(親子は P_ParentId で復元)
|
|
252
|
-
const options = await
|
|
256
|
+
const options = await t.option.search({ alias: "Option.P_Gender" });
|
|
253
257
|
```
|
|
254
258
|
|
|
255
|
-
- `
|
|
259
|
+
- `t.option.search()` は入れ子の選択肢ツリーを**深さ優先でフラット化**して返します(全ノード・`P_ParentId`/`P_Order` で階層復元可)。`start` が無いため `searchAll` はありません。
|
|
256
260
|
- `porters.partition.current()` は提供しません(`request_type=0` は既定の `code_direct` 認証では 403 になるため)。一覧は `search()`(既定 `requestType: 1`)で取得します。
|
|
257
261
|
|
|
258
262
|
## 読み取り値の表現
|
|
@@ -272,7 +276,7 @@ PORTERS の Field Type に応じてデコードされます。
|
|
|
272
276
|
| 空・未設定 | `null` |
|
|
273
277
|
|
|
274
278
|
```ts
|
|
275
|
-
const c = await
|
|
279
|
+
const c = await t.candidate.get(10001);
|
|
276
280
|
c?.P_Id; // number
|
|
277
281
|
c?.P_Name; // string | null
|
|
278
282
|
c?.P_RegistrationDate; // "2026-01-02T03:04:05Z" | null
|
|
@@ -295,17 +299,17 @@ c?.P_Owner; // { P_Id, P_Name, ... } | null
|
|
|
295
299
|
|
|
296
300
|
```ts
|
|
297
301
|
// 作成(新規)
|
|
298
|
-
const newId = await
|
|
302
|
+
const newId = await t.candidate.create({
|
|
299
303
|
P_Owner: 5, // User 項目は id
|
|
300
304
|
P_Name: "鈴木 一郎",
|
|
301
305
|
P_Reading: "すずき いちろう",
|
|
302
306
|
});
|
|
303
307
|
|
|
304
308
|
// 更新
|
|
305
|
-
await
|
|
309
|
+
await t.candidate.update(newId, { P_Mail: "ichiro@example.com" });
|
|
306
310
|
|
|
307
311
|
// 選考プロセス(関連 id を指定)
|
|
308
|
-
await
|
|
312
|
+
await t.process.create({
|
|
309
313
|
P_Owner: 1,
|
|
310
314
|
P_Client: 100,
|
|
311
315
|
P_Recruiter: 200,
|
|
@@ -315,7 +319,7 @@ await porters.process.create({
|
|
|
315
319
|
});
|
|
316
320
|
|
|
317
321
|
// 一括作成/更新(200 件+サイズで自動分割・部分成功を返す)
|
|
318
|
-
const bulk = await
|
|
322
|
+
const bulk = await t.candidate.createMany([
|
|
319
323
|
{ P_Owner: 5, P_Name: "山田 太郎" },
|
|
320
324
|
{ P_Owner: 5, P_Name: "鈴木 花子" },
|
|
321
325
|
]);
|
|
@@ -331,7 +335,7 @@ if (bulk.hasFailures) console.warn(bulk.failed); // per-item は throw せず結
|
|
|
331
335
|
```ts
|
|
332
336
|
import { bytesToBase64 } from "@joymerrevent/porters-connect";
|
|
333
337
|
|
|
334
|
-
const id = await
|
|
338
|
+
const id = await t.attachment.create({
|
|
335
339
|
resource: 17, // 関連リソース種別コード(Resource List 参照)
|
|
336
340
|
resourceId: 10001, // 関連レコードの id
|
|
337
341
|
contentType: "application/pdf",
|
|
@@ -351,7 +355,7 @@ const id = await porters.attachment.create({
|
|
|
351
355
|
import { PortersError } from "@joymerrevent/porters-connect";
|
|
352
356
|
|
|
353
357
|
try {
|
|
354
|
-
await
|
|
358
|
+
await t.candidate.get(1);
|
|
355
359
|
} catch (e) {
|
|
356
360
|
if (e instanceof PortersError) {
|
|
357
361
|
e.category; // "auth" | "permission" | "notFound" | "conflict" | "network" | ...
|
|
@@ -365,7 +369,7 @@ try {
|
|
|
365
369
|
|
|
366
370
|
- トークン失効は内側で自動回復します。設定ミスは `PortersConfigError` で早期に落とします。
|
|
367
371
|
- **`Promise` を返す公開メソッドは同期 throw しません**([ADR-0046][adr46])。設定ミスも含め常に **reject** で届くので、
|
|
368
|
-
`
|
|
372
|
+
`t.candidate.search(q).catch(handler)` でも捕まえられます(`string` を返す `auth.authorizationUrl` や
|
|
369
373
|
コンストラクタなど、Promise を返さない API は同期 throw のままです)。
|
|
370
374
|
- 一時エラー・ネットワークは内蔵リトライ。非冪等な `create` はネットワーク不確実時に握り潰さず表面化します。
|
|
371
375
|
- レート制限超過時、PORTERS は判別可能なコードを返さず接続を切るため、`PortersNetworkError`(category `"network"`)として表面化します。
|