@exabugs/dynamodb-client 0.1.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 +41 -0
- package/LICENSE +21 -0
- package/README.md +283 -0
- package/dist/client/Collection.d.ts +57 -0
- package/dist/client/Collection.d.ts.map +1 -0
- package/dist/client/Collection.js +174 -0
- package/dist/client/Collection.js.map +1 -0
- package/dist/client/Database.d.ts +35 -0
- package/dist/client/Database.d.ts.map +1 -0
- package/dist/client/Database.js +48 -0
- package/dist/client/Database.js.map +1 -0
- package/dist/client/DynamoClient.d.ts +43 -0
- package/dist/client/DynamoClient.d.ts.map +1 -0
- package/dist/client/DynamoClient.js +62 -0
- package/dist/client/DynamoClient.js.map +1 -0
- package/dist/client/FindCursor.d.ts +174 -0
- package/dist/client/FindCursor.d.ts.map +1 -0
- package/dist/client/FindCursor.js +256 -0
- package/dist/client/FindCursor.js.map +1 -0
- package/dist/client/aws-sigv4.d.ts +10 -0
- package/dist/client/aws-sigv4.d.ts.map +1 -0
- package/dist/client/aws-sigv4.js +54 -0
- package/dist/client/aws-sigv4.js.map +1 -0
- package/dist/client/index.cognito.d.ts +34 -0
- package/dist/client/index.cognito.d.ts.map +1 -0
- package/dist/client/index.cognito.js +30 -0
- package/dist/client/index.cognito.js.map +1 -0
- package/dist/client/index.d.ts +12 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.iam.d.ts +34 -0
- package/dist/client/index.iam.d.ts.map +1 -0
- package/dist/client/index.iam.js +28 -0
- package/dist/client/index.iam.js.map +1 -0
- package/dist/client/index.js +12 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/index.token.d.ts +33 -0
- package/dist/client/index.token.d.ts.map +1 -0
- package/dist/client/index.token.js +28 -0
- package/dist/client/index.token.js.map +1 -0
- package/dist/dynamodb.d.ts +20 -0
- package/dist/dynamodb.d.ts.map +1 -0
- package/dist/dynamodb.js +31 -0
- package/dist/dynamodb.js.map +1 -0
- package/dist/errors.d.ts +100 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +146 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/react-admin/dataProvider.d.ts +59 -0
- package/dist/integrations/react-admin/dataProvider.d.ts.map +1 -0
- package/dist/integrations/react-admin/dataProvider.js +364 -0
- package/dist/integrations/react-admin/dataProvider.js.map +1 -0
- package/dist/integrations/react-admin/index.d.ts +24 -0
- package/dist/integrations/react-admin/index.d.ts.map +1 -0
- package/dist/integrations/react-admin/index.js +23 -0
- package/dist/integrations/react-admin/index.js.map +1 -0
- package/dist/integrations/react-admin/types.d.ts +47 -0
- package/dist/integrations/react-admin/types.d.ts.map +1 -0
- package/dist/integrations/react-admin/types.js +5 -0
- package/dist/integrations/react-admin/types.js.map +1 -0
- package/dist/logger.d.ts +61 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +87 -0
- package/dist/logger.js.map +1 -0
- package/dist/scripts/repair-shadows.d.ts +3 -0
- package/dist/scripts/repair-shadows.d.ts.map +1 -0
- package/dist/scripts/repair-shadows.js +190 -0
- package/dist/scripts/repair-shadows.js.map +1 -0
- package/dist/server/handler.cjs +31378 -0
- package/dist/server/handler.cjs.map +7 -0
- package/dist/server/handler.d.ts +18 -0
- package/dist/server/handler.d.ts.map +1 -0
- package/dist/server/handler.js +435 -0
- package/dist/server/handler.js.map +1 -0
- package/dist/server/handler.zip +0 -0
- package/dist/server/index.d.ts +8 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +8 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/operations/deleteMany.d.ts +18 -0
- package/dist/server/operations/deleteMany.d.ts.map +1 -0
- package/dist/server/operations/deleteMany.js +222 -0
- package/dist/server/operations/deleteMany.js.map +1 -0
- package/dist/server/operations/deleteOne.d.ts +17 -0
- package/dist/server/operations/deleteOne.d.ts.map +1 -0
- package/dist/server/operations/deleteOne.js +87 -0
- package/dist/server/operations/deleteOne.js.map +1 -0
- package/dist/server/operations/find.d.ts +18 -0
- package/dist/server/operations/find.d.ts.map +1 -0
- package/dist/server/operations/find.js +382 -0
- package/dist/server/operations/find.js.map +1 -0
- package/dist/server/operations/findMany.d.ts +13 -0
- package/dist/server/operations/findMany.d.ts.map +1 -0
- package/dist/server/operations/findMany.js +61 -0
- package/dist/server/operations/findMany.js.map +1 -0
- package/dist/server/operations/findManyReference.d.ts +18 -0
- package/dist/server/operations/findManyReference.d.ts.map +1 -0
- package/dist/server/operations/findManyReference.js +150 -0
- package/dist/server/operations/findManyReference.js.map +1 -0
- package/dist/server/operations/findOne.d.ts +14 -0
- package/dist/server/operations/findOne.d.ts.map +1 -0
- package/dist/server/operations/findOne.js +56 -0
- package/dist/server/operations/findOne.js.map +1 -0
- package/dist/server/operations/insertMany.d.ts +19 -0
- package/dist/server/operations/insertMany.d.ts.map +1 -0
- package/dist/server/operations/insertMany.js +243 -0
- package/dist/server/operations/insertMany.js.map +1 -0
- package/dist/server/operations/insertOne.d.ts +18 -0
- package/dist/server/operations/insertOne.d.ts.map +1 -0
- package/dist/server/operations/insertOne.js +85 -0
- package/dist/server/operations/insertOne.js.map +1 -0
- package/dist/server/operations/updateMany.d.ts +20 -0
- package/dist/server/operations/updateMany.d.ts.map +1 -0
- package/dist/server/operations/updateMany.js +316 -0
- package/dist/server/operations/updateMany.js.map +1 -0
- package/dist/server/operations/updateOne.d.ts +20 -0
- package/dist/server/operations/updateOne.d.ts.map +1 -0
- package/dist/server/operations/updateOne.js +159 -0
- package/dist/server/operations/updateOne.js.map +1 -0
- package/dist/server/query/converter.d.ts +85 -0
- package/dist/server/query/converter.d.ts.map +1 -0
- package/dist/server/query/converter.js +161 -0
- package/dist/server/query/converter.js.map +1 -0
- package/dist/server/query/index.d.ts +5 -0
- package/dist/server/query/index.d.ts.map +1 -0
- package/dist/server/query/index.js +5 -0
- package/dist/server/query/index.js.map +1 -0
- package/dist/server/shadow/config.d.ts +147 -0
- package/dist/server/shadow/config.d.ts.map +1 -0
- package/dist/server/shadow/config.js +162 -0
- package/dist/server/shadow/config.js.map +1 -0
- package/dist/server/shadow/differ.d.ts +42 -0
- package/dist/server/shadow/differ.d.ts.map +1 -0
- package/dist/server/shadow/differ.js +66 -0
- package/dist/server/shadow/differ.js.map +1 -0
- package/dist/server/shadow/generator.d.ts +104 -0
- package/dist/server/shadow/generator.d.ts.map +1 -0
- package/dist/server/shadow/generator.js +148 -0
- package/dist/server/shadow/generator.js.map +1 -0
- package/dist/server/shadow/index.d.ts +11 -0
- package/dist/server/shadow/index.d.ts.map +1 -0
- package/dist/server/shadow/index.js +11 -0
- package/dist/server/shadow/index.js.map +1 -0
- package/dist/server/shadow/types.d.ts +44 -0
- package/dist/server/shadow/types.d.ts.map +1 -0
- package/dist/server/shadow/types.js +2 -0
- package/dist/server/shadow/types.js.map +1 -0
- package/dist/server/types.d.ts +295 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +7 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server/utils/auth.d.ts +43 -0
- package/dist/server/utils/auth.d.ts.map +1 -0
- package/dist/server/utils/auth.js +123 -0
- package/dist/server/utils/auth.js.map +1 -0
- package/dist/server/utils/bulkOperations.d.ts +81 -0
- package/dist/server/utils/bulkOperations.d.ts.map +1 -0
- package/dist/server/utils/bulkOperations.js +147 -0
- package/dist/server/utils/bulkOperations.js.map +1 -0
- package/dist/server/utils/chunking.d.ts +96 -0
- package/dist/server/utils/chunking.d.ts.map +1 -0
- package/dist/server/utils/chunking.js +225 -0
- package/dist/server/utils/chunking.js.map +1 -0
- package/dist/server/utils/dynamodb.d.ts +41 -0
- package/dist/server/utils/dynamodb.d.ts.map +1 -0
- package/dist/server/utils/dynamodb.js +83 -0
- package/dist/server/utils/dynamodb.js.map +1 -0
- package/dist/server/utils/filter.d.ts +152 -0
- package/dist/server/utils/filter.d.ts.map +1 -0
- package/dist/server/utils/filter.js +270 -0
- package/dist/server/utils/filter.js.map +1 -0
- package/dist/server/utils/pagination.d.ts +27 -0
- package/dist/server/utils/pagination.d.ts.map +1 -0
- package/dist/server/utils/pagination.js +56 -0
- package/dist/server/utils/pagination.js.map +1 -0
- package/dist/server/utils/timestamps.d.ts +31 -0
- package/dist/server/utils/timestamps.d.ts.map +1 -0
- package/dist/server/utils/timestamps.js +84 -0
- package/dist/server/utils/timestamps.js.map +1 -0
- package/dist/server/utils/ttl.d.ts +17 -0
- package/dist/server/utils/ttl.d.ts.map +1 -0
- package/dist/server/utils/ttl.js +62 -0
- package/dist/server/utils/ttl.js.map +1 -0
- package/dist/server/utils/validation.d.ts +40 -0
- package/dist/server/utils/validation.d.ts.map +1 -0
- package/dist/server/utils/validation.js +54 -0
- package/dist/server/utils/validation.js.map +1 -0
- package/dist/shadows/config.d.ts +54 -0
- package/dist/shadows/config.d.ts.map +1 -0
- package/dist/shadows/config.js +95 -0
- package/dist/shadows/config.js.map +1 -0
- package/dist/shadows/differ.d.ts +42 -0
- package/dist/shadows/differ.d.ts.map +1 -0
- package/dist/shadows/differ.js +66 -0
- package/dist/shadows/differ.js.map +1 -0
- package/dist/shadows/generator.d.ts +63 -0
- package/dist/shadows/generator.d.ts.map +1 -0
- package/dist/shadows/generator.js +107 -0
- package/dist/shadows/generator.js.map +1 -0
- package/dist/shadows/index.d.ts +15 -0
- package/dist/shadows/index.d.ts.map +1 -0
- package/dist/shadows/index.js +17 -0
- package/dist/shadows/index.js.map +1 -0
- package/dist/shadows/types.d.ts +44 -0
- package/dist/shadows/types.d.ts.map +1 -0
- package/dist/shadows/types.js +2 -0
- package/dist/shadows/types.js.map +1 -0
- package/dist/types.d.ts +165 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ulid.d.ts +46 -0
- package/dist/ulid.d.ts.map +1 -0
- package/dist/ulid.js +66 -0
- package/dist/ulid.js.map +1 -0
- package/package.json +136 -0
- package/terraform/README.md +222 -0
- package/terraform/examples/advanced/README.md +129 -0
- package/terraform/examples/advanced/main.tf +158 -0
- package/terraform/examples/advanced/shadow.config.json +35 -0
- package/terraform/examples/advanced/variables.tf +28 -0
- package/terraform/examples/basic/README.md +53 -0
- package/terraform/examples/basic/main.tf +99 -0
- package/terraform/examples/basic/variables.tf +17 -0
- package/terraform/main.tf +159 -0
- package/terraform/outputs.tf +56 -0
- package/terraform/variables.tf +59 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* updateMany 操作
|
|
3
|
+
* 複数レコードを一括更新する(JSON Merge Patch形式)
|
|
4
|
+
*
|
|
5
|
+
* 要件: 4.2, 4.4, 5.2, 5.3, 7.4, 13.1, 13.2, 13.3, 13.8, 13.12
|
|
6
|
+
*/
|
|
7
|
+
import { BatchGetCommand, TransactWriteCommand } from '@aws-sdk/lib-dynamodb';
|
|
8
|
+
import { createLogger, generateShadowRecords, getResourceSchema, getShadowConfig, } from '../../index.js';
|
|
9
|
+
import { calculateShadowDiff, generateMainRecordSK } from '../shadow/index.js';
|
|
10
|
+
import { calculateTimeoutRisk, logBulkOperationComplete, logLargeBatchWarning, logPartialFailure, logPreparationTimeoutRisk, } from '../utils/bulkOperations.js';
|
|
11
|
+
import { calculateChunks, executeChunks } from '../utils/chunking.js';
|
|
12
|
+
import { executeDynamoDBOperation, getDBClient, getTableName, removeShadowKeys, } from '../utils/dynamodb.js';
|
|
13
|
+
import { addUpdateTimestamp } from '../utils/timestamps.js';
|
|
14
|
+
const logger = createLogger({ service: 'records-lambda' });
|
|
15
|
+
/**
|
|
16
|
+
* JSON Merge Patch (RFC 7396) を適用する
|
|
17
|
+
*
|
|
18
|
+
* @param target - 対象オブジェクト
|
|
19
|
+
* @param patch - パッチオブジェクト
|
|
20
|
+
* @returns マージされたオブジェクト
|
|
21
|
+
*/
|
|
22
|
+
function applyJsonMergePatch(target, patch) {
|
|
23
|
+
const result = { ...target };
|
|
24
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
25
|
+
if (value === null) {
|
|
26
|
+
delete result[key];
|
|
27
|
+
}
|
|
28
|
+
else if (typeof value === 'object' &&
|
|
29
|
+
!Array.isArray(value) &&
|
|
30
|
+
value !== null &&
|
|
31
|
+
typeof result[key] === 'object' &&
|
|
32
|
+
!Array.isArray(result[key]) &&
|
|
33
|
+
result[key] !== null) {
|
|
34
|
+
result[key] = applyJsonMergePatch(result[key], value);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
result[key] = value;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* updateMany 操作を実行する
|
|
44
|
+
*
|
|
45
|
+
* 処理フロー:
|
|
46
|
+
* 1. BatchGetItemで既存レコードを取得
|
|
47
|
+
* 2. 各レコードにJSON Merge Patchを適用
|
|
48
|
+
* 3. updatedAtタイムスタンプを更新
|
|
49
|
+
* 4. 新しいシャドーSKを生成し、差分を計算
|
|
50
|
+
* 5. アイテム数を計算してチャンク分割(1 + 削除シャドー数 + 追加シャドー数)
|
|
51
|
+
* 6. 各チャンクをTransactWriteItemsで順次実行
|
|
52
|
+
* 7. 部分失敗をハンドリング
|
|
53
|
+
*
|
|
54
|
+
* @param resource - リソース名
|
|
55
|
+
* @param params - updateManyパラメータ
|
|
56
|
+
* @param requestId - リクエストID
|
|
57
|
+
* @returns 更新結果(成功レコード、失敗ID、エラー情報)
|
|
58
|
+
*/
|
|
59
|
+
export async function handleUpdateMany(resource, params, requestId) {
|
|
60
|
+
const { ids, data: patchData } = params;
|
|
61
|
+
const startTime = Date.now();
|
|
62
|
+
logger.debug('Executing updateMany', {
|
|
63
|
+
requestId,
|
|
64
|
+
resource,
|
|
65
|
+
count: ids.length,
|
|
66
|
+
});
|
|
67
|
+
// IDが空の場合は空レスポンスを返す
|
|
68
|
+
if (ids.length === 0) {
|
|
69
|
+
return {
|
|
70
|
+
count: 0,
|
|
71
|
+
successIds: {},
|
|
72
|
+
failedIds: {},
|
|
73
|
+
errors: {},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// 大量レコード処理時の警告ログ出力(要件: 13.12)
|
|
77
|
+
logLargeBatchWarning('updateMany', ids.length, requestId, resource);
|
|
78
|
+
const dbClient = getDBClient();
|
|
79
|
+
const tableName = getTableName();
|
|
80
|
+
// BatchGetItemで既存レコードを取得
|
|
81
|
+
const keys = ids.map((id) => ({
|
|
82
|
+
PK: resource,
|
|
83
|
+
SK: generateMainRecordSK(id),
|
|
84
|
+
}));
|
|
85
|
+
const batchGetResult = await executeDynamoDBOperation(() => dbClient.send(new BatchGetCommand({
|
|
86
|
+
RequestItems: {
|
|
87
|
+
[tableName]: {
|
|
88
|
+
Keys: keys,
|
|
89
|
+
ConsistentRead: true,
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
})), 'BatchGetItem');
|
|
93
|
+
const existingItems = batchGetResult.Responses?.[tableName] || [];
|
|
94
|
+
// 存在するレコードのIDセットを作成
|
|
95
|
+
const existingIds = new Set(existingItems.map((item) => {
|
|
96
|
+
const data = item.data;
|
|
97
|
+
return data.id;
|
|
98
|
+
}));
|
|
99
|
+
// 存在しないIDを特定
|
|
100
|
+
const notFoundIds = ids.filter((id) => !existingIds.has(id));
|
|
101
|
+
// シャドー設定を取得(環境変数からキャッシュ付き)
|
|
102
|
+
const shadowConfig = getShadowConfig();
|
|
103
|
+
const shadowSchema = getResourceSchema(shadowConfig, resource);
|
|
104
|
+
const preparedRecords = [];
|
|
105
|
+
const preparationFailedIds = [];
|
|
106
|
+
const preparationErrors = [];
|
|
107
|
+
// 各レコードを準備
|
|
108
|
+
for (const item of existingItems) {
|
|
109
|
+
try {
|
|
110
|
+
const existingData = item.data;
|
|
111
|
+
const id = existingData.id;
|
|
112
|
+
const oldShadowKeys = existingData.__shadowKeys || [];
|
|
113
|
+
// JSON Merge Patchを適用
|
|
114
|
+
const mergedData = applyJsonMergePatch(removeShadowKeys(existingData), patchData);
|
|
115
|
+
// updatedAt を更新(タイムスタンプフィールド名は動的に取得)
|
|
116
|
+
const updatedData = addUpdateTimestamp({
|
|
117
|
+
...mergedData,
|
|
118
|
+
id,
|
|
119
|
+
});
|
|
120
|
+
// 新しいシャドーレコードを生成
|
|
121
|
+
const newShadowRecords = generateShadowRecords(updatedData, shadowSchema);
|
|
122
|
+
const newShadowKeys = newShadowRecords.map((shadow) => shadow.SK);
|
|
123
|
+
// メインレコードのSKを生成
|
|
124
|
+
const mainSK = generateMainRecordSK(id);
|
|
125
|
+
preparedRecords.push({
|
|
126
|
+
id,
|
|
127
|
+
updatedData,
|
|
128
|
+
oldShadowKeys,
|
|
129
|
+
newShadowKeys,
|
|
130
|
+
mainSK,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
// 準備段階で失敗したレコードを記録
|
|
135
|
+
const existingData = item.data;
|
|
136
|
+
const failedId = existingData.id || 'unknown-id';
|
|
137
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown preparation error';
|
|
138
|
+
const errorCode = getPreparationErrorCode(error);
|
|
139
|
+
logger.error('Failed to prepare record for update', {
|
|
140
|
+
requestId,
|
|
141
|
+
recordId: failedId,
|
|
142
|
+
error: errorMessage,
|
|
143
|
+
errorCode,
|
|
144
|
+
});
|
|
145
|
+
// 準備失敗をエラーリストに追加
|
|
146
|
+
preparationFailedIds.push(failedId);
|
|
147
|
+
preparationErrors.push({
|
|
148
|
+
id: failedId,
|
|
149
|
+
code: errorCode,
|
|
150
|
+
message: errorMessage,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// アイテム数計算関数(1 + 削除シャドー数 + 追加シャドー数)
|
|
155
|
+
const getItemCount = (record) => {
|
|
156
|
+
const shadowDiff = calculateShadowDiff(record.oldShadowKeys, record.newShadowKeys);
|
|
157
|
+
return 1 + shadowDiff.toDelete.length + shadowDiff.toAdd.length;
|
|
158
|
+
};
|
|
159
|
+
// チャンク分割
|
|
160
|
+
const { chunks } = calculateChunks(preparedRecords, getItemCount);
|
|
161
|
+
// 準備段階の経過時間をチェック(要件: 13.12)
|
|
162
|
+
const preparationRiskInfo = calculateTimeoutRisk(startTime);
|
|
163
|
+
logPreparationTimeoutRisk(requestId, resource, preparedRecords.length, chunks.length, preparationRiskInfo);
|
|
164
|
+
// チャンク実行関数
|
|
165
|
+
const executeChunk = async (chunk) => {
|
|
166
|
+
const transactItems = [];
|
|
167
|
+
// チャンク内の各レコードをTransactItemsに変換
|
|
168
|
+
for (const record of chunk) {
|
|
169
|
+
// シャドー差分を計算
|
|
170
|
+
const shadowDiff = calculateShadowDiff(record.oldShadowKeys, record.newShadowKeys);
|
|
171
|
+
// メインレコードを更新
|
|
172
|
+
transactItems.push({
|
|
173
|
+
Put: {
|
|
174
|
+
TableName: tableName,
|
|
175
|
+
Item: {
|
|
176
|
+
PK: resource,
|
|
177
|
+
SK: record.mainSK,
|
|
178
|
+
data: {
|
|
179
|
+
...record.updatedData,
|
|
180
|
+
__shadowKeys: record.newShadowKeys,
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
// 旧シャドーを削除
|
|
186
|
+
for (const shadowSK of shadowDiff.toDelete) {
|
|
187
|
+
transactItems.push({
|
|
188
|
+
Delete: {
|
|
189
|
+
TableName: tableName,
|
|
190
|
+
Key: {
|
|
191
|
+
PK: resource,
|
|
192
|
+
SK: shadowSK,
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
// 新シャドーを追加
|
|
198
|
+
for (const shadowSK of shadowDiff.toAdd) {
|
|
199
|
+
transactItems.push({
|
|
200
|
+
Put: {
|
|
201
|
+
TableName: tableName,
|
|
202
|
+
Item: {
|
|
203
|
+
PK: resource,
|
|
204
|
+
SK: shadowSK,
|
|
205
|
+
data: {},
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
// TransactWriteItemsを実行
|
|
212
|
+
await executeDynamoDBOperation(() => dbClient.send(new TransactWriteCommand({
|
|
213
|
+
TransactItems: transactItems,
|
|
214
|
+
})), 'TransactWriteItems');
|
|
215
|
+
// 成功したレコードを返す
|
|
216
|
+
return chunk;
|
|
217
|
+
};
|
|
218
|
+
// チャンクを順次実行
|
|
219
|
+
const { successRecords, failedIds: chunkFailedIds, errors: chunkErrors, } = await executeChunks(chunks, executeChunk, (record) => record.id);
|
|
220
|
+
// 統一レスポンス形式を構築
|
|
221
|
+
// successIds: インデックス付きオブジェクト(元の配列のインデックスとIDのマッピング)
|
|
222
|
+
const successIds = {};
|
|
223
|
+
const failedIdsMap = {};
|
|
224
|
+
const errorsMap = {};
|
|
225
|
+
// 成功したレコードのインデックスを特定
|
|
226
|
+
const successIdSet = new Set(successRecords.map((r) => r.id));
|
|
227
|
+
for (let i = 0; i < ids.length; i++) {
|
|
228
|
+
const id = ids[i];
|
|
229
|
+
if (successIdSet.has(id)) {
|
|
230
|
+
successIds[i] = id;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// 存在しないIDのインデックスを特定
|
|
234
|
+
for (let i = 0; i < ids.length; i++) {
|
|
235
|
+
const id = ids[i];
|
|
236
|
+
if (notFoundIds.includes(id)) {
|
|
237
|
+
failedIdsMap[i] = id;
|
|
238
|
+
errorsMap[i] = {
|
|
239
|
+
id,
|
|
240
|
+
code: 'ITEM_NOT_FOUND',
|
|
241
|
+
message: `Record not found: ${id}`,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// 準備失敗のインデックスを特定
|
|
246
|
+
for (let i = 0; i < ids.length; i++) {
|
|
247
|
+
const id = ids[i];
|
|
248
|
+
if (preparationFailedIds.includes(id)) {
|
|
249
|
+
failedIdsMap[i] = id;
|
|
250
|
+
const error = preparationErrors.find((e) => e.id === id);
|
|
251
|
+
if (error) {
|
|
252
|
+
errorsMap[i] = error;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// チャンク実行失敗のインデックスを特定
|
|
257
|
+
for (let i = 0; i < ids.length; i++) {
|
|
258
|
+
const id = ids[i];
|
|
259
|
+
if (chunkFailedIds.includes(id)) {
|
|
260
|
+
failedIdsMap[i] = id;
|
|
261
|
+
const error = chunkErrors.find((e) => e.id === id);
|
|
262
|
+
if (error) {
|
|
263
|
+
errorsMap[i] = {
|
|
264
|
+
id: error.id,
|
|
265
|
+
code: error.code,
|
|
266
|
+
message: error.message,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
const count = Object.keys(successIds).length;
|
|
272
|
+
const allFailedIds = Object.values(failedIdsMap);
|
|
273
|
+
// 総実行時間を計算(要件: 13.12)
|
|
274
|
+
const completionRiskInfo = calculateTimeoutRisk(startTime);
|
|
275
|
+
logBulkOperationComplete('updateMany', requestId, resource, ids.length, count, allFailedIds.length, completionRiskInfo, {
|
|
276
|
+
updated: count,
|
|
277
|
+
notFound: notFoundIds.length,
|
|
278
|
+
preparationFailed: preparationFailedIds.length,
|
|
279
|
+
chunkExecutionFailed: chunkFailedIds.length,
|
|
280
|
+
});
|
|
281
|
+
// 部分失敗の場合、詳細なエラーサマリーをログ出力
|
|
282
|
+
if (allFailedIds.length > 0) {
|
|
283
|
+
logPartialFailure('updateMany', requestId, resource, ids.length, count, allFailedIds.length, Object.values(errorsMap).map((e) => e.code), {
|
|
284
|
+
notFoundCount: notFoundIds.length,
|
|
285
|
+
preparationFailures: preparationFailedIds.length,
|
|
286
|
+
chunkExecutionFailures: chunkFailedIds.length,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
// 統一レスポンス形式で返却
|
|
290
|
+
return {
|
|
291
|
+
count,
|
|
292
|
+
successIds,
|
|
293
|
+
failedIds: failedIdsMap,
|
|
294
|
+
errors: errorsMap,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* 準備段階のエラーからエラーコードを抽出する
|
|
299
|
+
*
|
|
300
|
+
* @param error - エラーオブジェクト
|
|
301
|
+
* @returns エラーコード
|
|
302
|
+
*/
|
|
303
|
+
function getPreparationErrorCode(error) {
|
|
304
|
+
if (error && typeof error === 'object') {
|
|
305
|
+
// カスタムエラー
|
|
306
|
+
if ('code' in error && typeof error.code === 'string') {
|
|
307
|
+
return error.code;
|
|
308
|
+
}
|
|
309
|
+
// AWS SDK エラー
|
|
310
|
+
if ('name' in error && typeof error.name === 'string') {
|
|
311
|
+
return error.name;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return 'VALIDATION_ERROR';
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=updateMany.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updateMany.js","sourceRoot":"","sources":["../../../src/server/operations/updateMany.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { UpdateOneParams, UpdateOneResult } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* updateOne 操作を実行する
|
|
4
|
+
*
|
|
5
|
+
* 処理フロー:
|
|
6
|
+
* 1. GetItemで既存レコードを取得
|
|
7
|
+
* 2. JSON Merge Patchを適用
|
|
8
|
+
* 3. updatedAtタイムスタンプを更新
|
|
9
|
+
* 4. 新しいシャドーSKを生成
|
|
10
|
+
* 5. 旧シャドーと新シャドーの差分を計算
|
|
11
|
+
* 6. TransactWriteItemsでメインレコード更新 + 旧シャドー削除 + 新シャドー追加
|
|
12
|
+
*
|
|
13
|
+
* @param resource - リソース名
|
|
14
|
+
* @param params - updateOneパラメータ
|
|
15
|
+
* @param requestId - リクエストID
|
|
16
|
+
* @returns 更新されたレコード
|
|
17
|
+
* @throws {ItemNotFoundError} レコードが存在しない場合
|
|
18
|
+
*/
|
|
19
|
+
export declare function handleUpdateOne(resource: string, params: UpdateOneParams, requestId: string): Promise<UpdateOneResult>;
|
|
20
|
+
//# sourceMappingURL=updateOne.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updateOne.d.ts","sourceRoot":"","sources":["../../../src/server/operations/updateOne.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAuDpE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CA8H1B"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* updateOne 操作
|
|
3
|
+
* 単一レコードを更新する(JSON Merge Patch形式)
|
|
4
|
+
*
|
|
5
|
+
* 要件: 4.2, 4.4, 5.2, 5.3
|
|
6
|
+
*/
|
|
7
|
+
import { GetCommand, TransactWriteCommand } from '@aws-sdk/lib-dynamodb';
|
|
8
|
+
import { ItemNotFoundError, createLogger, generateShadowRecords, getResourceSchema, getShadowConfig, } from '../../index.js';
|
|
9
|
+
import { calculateShadowDiff, generateMainRecordSK, isDiffEmpty } from '../shadow/index.js';
|
|
10
|
+
import { executeDynamoDBOperation, getDBClient, getTableName, removeShadowKeys, } from '../utils/dynamodb.js';
|
|
11
|
+
import { addUpdateTimestamp } from '../utils/timestamps.js';
|
|
12
|
+
const logger = createLogger({ service: 'records-lambda' });
|
|
13
|
+
/**
|
|
14
|
+
* JSON Merge Patch (RFC 7396) を適用する
|
|
15
|
+
*
|
|
16
|
+
* ルール:
|
|
17
|
+
* - null値はフィールド削除を意味する
|
|
18
|
+
* - 配列は完全置換される
|
|
19
|
+
* - オブジェクトは再帰的にマージされる
|
|
20
|
+
*
|
|
21
|
+
* @param target - 対象オブジェクト
|
|
22
|
+
* @param patch - パッチオブジェクト
|
|
23
|
+
* @returns マージされたオブジェクト
|
|
24
|
+
*/
|
|
25
|
+
function applyJsonMergePatch(target, patch) {
|
|
26
|
+
const result = { ...target };
|
|
27
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
28
|
+
if (value === null) {
|
|
29
|
+
// null値はフィールド削除
|
|
30
|
+
delete result[key];
|
|
31
|
+
}
|
|
32
|
+
else if (typeof value === 'object' &&
|
|
33
|
+
!Array.isArray(value) &&
|
|
34
|
+
value !== null &&
|
|
35
|
+
typeof result[key] === 'object' &&
|
|
36
|
+
!Array.isArray(result[key]) &&
|
|
37
|
+
result[key] !== null) {
|
|
38
|
+
// オブジェクトは再帰的にマージ
|
|
39
|
+
result[key] = applyJsonMergePatch(result[key], value);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// その他(配列、プリミティブ)は完全置換
|
|
43
|
+
result[key] = value;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* updateOne 操作を実行する
|
|
50
|
+
*
|
|
51
|
+
* 処理フロー:
|
|
52
|
+
* 1. GetItemで既存レコードを取得
|
|
53
|
+
* 2. JSON Merge Patchを適用
|
|
54
|
+
* 3. updatedAtタイムスタンプを更新
|
|
55
|
+
* 4. 新しいシャドーSKを生成
|
|
56
|
+
* 5. 旧シャドーと新シャドーの差分を計算
|
|
57
|
+
* 6. TransactWriteItemsでメインレコード更新 + 旧シャドー削除 + 新シャドー追加
|
|
58
|
+
*
|
|
59
|
+
* @param resource - リソース名
|
|
60
|
+
* @param params - updateOneパラメータ
|
|
61
|
+
* @param requestId - リクエストID
|
|
62
|
+
* @returns 更新されたレコード
|
|
63
|
+
* @throws {ItemNotFoundError} レコードが存在しない場合
|
|
64
|
+
*/
|
|
65
|
+
export async function handleUpdateOne(resource, params, requestId) {
|
|
66
|
+
const { id, data: patchData } = params;
|
|
67
|
+
logger.debug('Executing updateOne', {
|
|
68
|
+
requestId,
|
|
69
|
+
resource,
|
|
70
|
+
id,
|
|
71
|
+
});
|
|
72
|
+
const dbClient = getDBClient();
|
|
73
|
+
const tableName = getTableName();
|
|
74
|
+
// メインレコードのSKを生成
|
|
75
|
+
const mainSK = generateMainRecordSK(id);
|
|
76
|
+
// 既存レコードを取得
|
|
77
|
+
const getResult = await executeDynamoDBOperation(() => dbClient.send(new GetCommand({
|
|
78
|
+
TableName: tableName,
|
|
79
|
+
Key: {
|
|
80
|
+
PK: resource,
|
|
81
|
+
SK: mainSK,
|
|
82
|
+
},
|
|
83
|
+
ConsistentRead: true,
|
|
84
|
+
})), 'GetItem');
|
|
85
|
+
if (!getResult.Item) {
|
|
86
|
+
throw new ItemNotFoundError(`Record not found: ${id}`, { resource, id });
|
|
87
|
+
}
|
|
88
|
+
const existingData = getResult.Item.data;
|
|
89
|
+
const oldShadowKeys = existingData.__shadowKeys || [];
|
|
90
|
+
// JSON Merge Patchを適用
|
|
91
|
+
const mergedData = applyJsonMergePatch(removeShadowKeys(existingData), patchData);
|
|
92
|
+
// updatedAt を更新(タイムスタンプフィールド名は動的に取得)
|
|
93
|
+
const updatedData = addUpdateTimestamp({
|
|
94
|
+
...mergedData,
|
|
95
|
+
id, // IDは変更不可
|
|
96
|
+
});
|
|
97
|
+
// シャドー設定を取得(環境変数からキャッシュ付き)
|
|
98
|
+
const shadowConfig = getShadowConfig();
|
|
99
|
+
const shadowSchema = getResourceSchema(shadowConfig, resource);
|
|
100
|
+
// 新しいシャドーレコードを生成
|
|
101
|
+
const newShadowRecords = generateShadowRecords(updatedData, shadowSchema);
|
|
102
|
+
const newShadowKeys = newShadowRecords.map((shadow) => shadow.SK);
|
|
103
|
+
// シャドー差分を計算
|
|
104
|
+
const shadowDiff = calculateShadowDiff(oldShadowKeys, newShadowKeys);
|
|
105
|
+
// TransactWriteItemsで一括更新
|
|
106
|
+
const transactItems = [];
|
|
107
|
+
// メインレコードを更新
|
|
108
|
+
transactItems.push({
|
|
109
|
+
Put: {
|
|
110
|
+
TableName: tableName,
|
|
111
|
+
Item: {
|
|
112
|
+
PK: resource,
|
|
113
|
+
SK: mainSK,
|
|
114
|
+
data: {
|
|
115
|
+
...updatedData,
|
|
116
|
+
__shadowKeys: newShadowKeys,
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
// 旧シャドーを削除
|
|
122
|
+
for (const shadowSK of shadowDiff.toDelete) {
|
|
123
|
+
transactItems.push({
|
|
124
|
+
Delete: {
|
|
125
|
+
TableName: tableName,
|
|
126
|
+
Key: {
|
|
127
|
+
PK: resource,
|
|
128
|
+
SK: shadowSK,
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
// 新シャドーを追加
|
|
134
|
+
for (const shadowRecord of newShadowRecords) {
|
|
135
|
+
if (shadowDiff.toAdd.includes(shadowRecord.SK)) {
|
|
136
|
+
transactItems.push({
|
|
137
|
+
Put: {
|
|
138
|
+
TableName: tableName,
|
|
139
|
+
Item: shadowRecord,
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// トランザクション実行
|
|
145
|
+
await executeDynamoDBOperation(() => dbClient.send(new TransactWriteCommand({
|
|
146
|
+
TransactItems: transactItems,
|
|
147
|
+
})), 'TransactWriteItems');
|
|
148
|
+
logger.info('updateOne succeeded', {
|
|
149
|
+
requestId,
|
|
150
|
+
resource,
|
|
151
|
+
id,
|
|
152
|
+
shadowDiffEmpty: isDiffEmpty(shadowDiff),
|
|
153
|
+
shadowsDeleted: shadowDiff.toDelete.length,
|
|
154
|
+
shadowsAdded: shadowDiff.toAdd.length,
|
|
155
|
+
});
|
|
156
|
+
// __shadowKeysを除外してレスポンスを返す
|
|
157
|
+
return removeShadowKeys(updatedData);
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=updateOne.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updateOne.js","sourceRoot":"","sources":["../../../src/server/operations/updateOne.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* クエリ変換ユーティリティ
|
|
3
|
+
*
|
|
4
|
+
* MongoDB風のFilterをDynamoDB形式に変換します。
|
|
5
|
+
*
|
|
6
|
+
* 要件: 8.5
|
|
7
|
+
*/
|
|
8
|
+
import type { Filter } from '../../types.js';
|
|
9
|
+
/**
|
|
10
|
+
* DynamoDB比較演算子
|
|
11
|
+
*/
|
|
12
|
+
export type DynamoComparisonOperator = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'nin' | 'exists' | 'begins_with' | 'contains';
|
|
13
|
+
/**
|
|
14
|
+
* DynamoDB条件
|
|
15
|
+
*/
|
|
16
|
+
export interface DynamoCondition {
|
|
17
|
+
/** フィールド名 */
|
|
18
|
+
field: string;
|
|
19
|
+
/** 比較演算子 */
|
|
20
|
+
operator: DynamoComparisonOperator;
|
|
21
|
+
/** 比較値 */
|
|
22
|
+
value: unknown;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* DynamoDBクエリ
|
|
26
|
+
*/
|
|
27
|
+
export interface DynamoQuery {
|
|
28
|
+
/** パーティションキー(リソース名) */
|
|
29
|
+
pk: string;
|
|
30
|
+
/** 条件の配列 */
|
|
31
|
+
conditions: DynamoCondition[];
|
|
32
|
+
/** 論理演算子(デフォルト: AND) */
|
|
33
|
+
logicalOperator?: 'AND' | 'OR';
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* FilterをDynamoDB形式に変換する
|
|
37
|
+
*
|
|
38
|
+
* MongoDB風のFilter構文をDynamoDBのFilterExpression用の条件配列に変換します。
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* // 単純な等価条件
|
|
43
|
+
* const filter: Filter<Product> = { status: 'active' };
|
|
44
|
+
* const query = convertFilterToDynamo('products', filter);
|
|
45
|
+
* // => { pk: 'products', conditions: [{ field: 'status', operator: 'eq', value: 'active' }] }
|
|
46
|
+
*
|
|
47
|
+
* // 演算子を使用した条件
|
|
48
|
+
* const filter: Filter<Product> = {
|
|
49
|
+
* price: { gte: 1000, lte: 5000 },
|
|
50
|
+
* status: { in: ['active', 'pending'] }
|
|
51
|
+
* };
|
|
52
|
+
* const query = convertFilterToDynamo('products', filter);
|
|
53
|
+
* // => {
|
|
54
|
+
* // pk: 'products',
|
|
55
|
+
* // conditions: [
|
|
56
|
+
* // { field: 'price', operator: 'gte', value: 1000 },
|
|
57
|
+
* // { field: 'price', operator: 'lte', value: 5000 },
|
|
58
|
+
* // { field: 'status', operator: 'in', value: ['active', 'pending'] }
|
|
59
|
+
* // ]
|
|
60
|
+
* // }
|
|
61
|
+
*
|
|
62
|
+
* // OR条件
|
|
63
|
+
* const filter: Filter<Product> = {
|
|
64
|
+
* or: [
|
|
65
|
+
* { status: 'active' },
|
|
66
|
+
* { priority: { gte: 5 } }
|
|
67
|
+
* ]
|
|
68
|
+
* };
|
|
69
|
+
* const query = convertFilterToDynamo('products', filter);
|
|
70
|
+
* // => {
|
|
71
|
+
* // pk: 'products',
|
|
72
|
+
* // conditions: [
|
|
73
|
+
* // { field: 'status', operator: 'eq', value: 'active' },
|
|
74
|
+
* // { field: 'priority', operator: 'gte', value: 5 }
|
|
75
|
+
* // ],
|
|
76
|
+
* // logicalOperator: 'OR'
|
|
77
|
+
* // }
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* @param collection - コレクション名(リソース名)
|
|
81
|
+
* @param filter - MongoDB風のフィルタ条件
|
|
82
|
+
* @returns DynamoDBクエリ
|
|
83
|
+
*/
|
|
84
|
+
export declare function convertFilterToDynamo<T = any>(collection: string, filter: Filter<T>): DynamoQuery;
|
|
85
|
+
//# sourceMappingURL=converter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converter.d.ts","sourceRoot":"","sources":["../../../src/server/query/converter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,MAAM,EAAmB,MAAM,gBAAgB,CAAC;AAE9D;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAChC,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,QAAQ,GACR,aAAa,GACb,UAAU,CAAC;AAEf;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,aAAa;IACb,KAAK,EAAE,MAAM,CAAC;IACd,YAAY;IACZ,QAAQ,EAAE,wBAAwB,CAAC;IACnC,UAAU;IACV,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY;IACZ,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,wBAAwB;IACxB,eAAe,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,GAAG,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,CAkEjG"}
|