@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.
Files changed (230) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/LICENSE +21 -0
  3. package/README.md +283 -0
  4. package/dist/client/Collection.d.ts +57 -0
  5. package/dist/client/Collection.d.ts.map +1 -0
  6. package/dist/client/Collection.js +174 -0
  7. package/dist/client/Collection.js.map +1 -0
  8. package/dist/client/Database.d.ts +35 -0
  9. package/dist/client/Database.d.ts.map +1 -0
  10. package/dist/client/Database.js +48 -0
  11. package/dist/client/Database.js.map +1 -0
  12. package/dist/client/DynamoClient.d.ts +43 -0
  13. package/dist/client/DynamoClient.d.ts.map +1 -0
  14. package/dist/client/DynamoClient.js +62 -0
  15. package/dist/client/DynamoClient.js.map +1 -0
  16. package/dist/client/FindCursor.d.ts +174 -0
  17. package/dist/client/FindCursor.d.ts.map +1 -0
  18. package/dist/client/FindCursor.js +256 -0
  19. package/dist/client/FindCursor.js.map +1 -0
  20. package/dist/client/aws-sigv4.d.ts +10 -0
  21. package/dist/client/aws-sigv4.d.ts.map +1 -0
  22. package/dist/client/aws-sigv4.js +54 -0
  23. package/dist/client/aws-sigv4.js.map +1 -0
  24. package/dist/client/index.cognito.d.ts +34 -0
  25. package/dist/client/index.cognito.d.ts.map +1 -0
  26. package/dist/client/index.cognito.js +30 -0
  27. package/dist/client/index.cognito.js.map +1 -0
  28. package/dist/client/index.d.ts +12 -0
  29. package/dist/client/index.d.ts.map +1 -0
  30. package/dist/client/index.iam.d.ts +34 -0
  31. package/dist/client/index.iam.d.ts.map +1 -0
  32. package/dist/client/index.iam.js +28 -0
  33. package/dist/client/index.iam.js.map +1 -0
  34. package/dist/client/index.js +12 -0
  35. package/dist/client/index.js.map +1 -0
  36. package/dist/client/index.token.d.ts +33 -0
  37. package/dist/client/index.token.d.ts.map +1 -0
  38. package/dist/client/index.token.js +28 -0
  39. package/dist/client/index.token.js.map +1 -0
  40. package/dist/dynamodb.d.ts +20 -0
  41. package/dist/dynamodb.d.ts.map +1 -0
  42. package/dist/dynamodb.js +31 -0
  43. package/dist/dynamodb.js.map +1 -0
  44. package/dist/errors.d.ts +100 -0
  45. package/dist/errors.d.ts.map +1 -0
  46. package/dist/errors.js +146 -0
  47. package/dist/errors.js.map +1 -0
  48. package/dist/index.d.ts +10 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +7 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/integrations/react-admin/dataProvider.d.ts +59 -0
  53. package/dist/integrations/react-admin/dataProvider.d.ts.map +1 -0
  54. package/dist/integrations/react-admin/dataProvider.js +364 -0
  55. package/dist/integrations/react-admin/dataProvider.js.map +1 -0
  56. package/dist/integrations/react-admin/index.d.ts +24 -0
  57. package/dist/integrations/react-admin/index.d.ts.map +1 -0
  58. package/dist/integrations/react-admin/index.js +23 -0
  59. package/dist/integrations/react-admin/index.js.map +1 -0
  60. package/dist/integrations/react-admin/types.d.ts +47 -0
  61. package/dist/integrations/react-admin/types.d.ts.map +1 -0
  62. package/dist/integrations/react-admin/types.js +5 -0
  63. package/dist/integrations/react-admin/types.js.map +1 -0
  64. package/dist/logger.d.ts +61 -0
  65. package/dist/logger.d.ts.map +1 -0
  66. package/dist/logger.js +87 -0
  67. package/dist/logger.js.map +1 -0
  68. package/dist/scripts/repair-shadows.d.ts +3 -0
  69. package/dist/scripts/repair-shadows.d.ts.map +1 -0
  70. package/dist/scripts/repair-shadows.js +190 -0
  71. package/dist/scripts/repair-shadows.js.map +1 -0
  72. package/dist/server/handler.cjs +31378 -0
  73. package/dist/server/handler.cjs.map +7 -0
  74. package/dist/server/handler.d.ts +18 -0
  75. package/dist/server/handler.d.ts.map +1 -0
  76. package/dist/server/handler.js +435 -0
  77. package/dist/server/handler.js.map +1 -0
  78. package/dist/server/handler.zip +0 -0
  79. package/dist/server/index.d.ts +8 -0
  80. package/dist/server/index.d.ts.map +1 -0
  81. package/dist/server/index.js +8 -0
  82. package/dist/server/index.js.map +1 -0
  83. package/dist/server/operations/deleteMany.d.ts +18 -0
  84. package/dist/server/operations/deleteMany.d.ts.map +1 -0
  85. package/dist/server/operations/deleteMany.js +222 -0
  86. package/dist/server/operations/deleteMany.js.map +1 -0
  87. package/dist/server/operations/deleteOne.d.ts +17 -0
  88. package/dist/server/operations/deleteOne.d.ts.map +1 -0
  89. package/dist/server/operations/deleteOne.js +87 -0
  90. package/dist/server/operations/deleteOne.js.map +1 -0
  91. package/dist/server/operations/find.d.ts +18 -0
  92. package/dist/server/operations/find.d.ts.map +1 -0
  93. package/dist/server/operations/find.js +382 -0
  94. package/dist/server/operations/find.js.map +1 -0
  95. package/dist/server/operations/findMany.d.ts +13 -0
  96. package/dist/server/operations/findMany.d.ts.map +1 -0
  97. package/dist/server/operations/findMany.js +61 -0
  98. package/dist/server/operations/findMany.js.map +1 -0
  99. package/dist/server/operations/findManyReference.d.ts +18 -0
  100. package/dist/server/operations/findManyReference.d.ts.map +1 -0
  101. package/dist/server/operations/findManyReference.js +150 -0
  102. package/dist/server/operations/findManyReference.js.map +1 -0
  103. package/dist/server/operations/findOne.d.ts +14 -0
  104. package/dist/server/operations/findOne.d.ts.map +1 -0
  105. package/dist/server/operations/findOne.js +56 -0
  106. package/dist/server/operations/findOne.js.map +1 -0
  107. package/dist/server/operations/insertMany.d.ts +19 -0
  108. package/dist/server/operations/insertMany.d.ts.map +1 -0
  109. package/dist/server/operations/insertMany.js +243 -0
  110. package/dist/server/operations/insertMany.js.map +1 -0
  111. package/dist/server/operations/insertOne.d.ts +18 -0
  112. package/dist/server/operations/insertOne.d.ts.map +1 -0
  113. package/dist/server/operations/insertOne.js +85 -0
  114. package/dist/server/operations/insertOne.js.map +1 -0
  115. package/dist/server/operations/updateMany.d.ts +20 -0
  116. package/dist/server/operations/updateMany.d.ts.map +1 -0
  117. package/dist/server/operations/updateMany.js +316 -0
  118. package/dist/server/operations/updateMany.js.map +1 -0
  119. package/dist/server/operations/updateOne.d.ts +20 -0
  120. package/dist/server/operations/updateOne.d.ts.map +1 -0
  121. package/dist/server/operations/updateOne.js +159 -0
  122. package/dist/server/operations/updateOne.js.map +1 -0
  123. package/dist/server/query/converter.d.ts +85 -0
  124. package/dist/server/query/converter.d.ts.map +1 -0
  125. package/dist/server/query/converter.js +161 -0
  126. package/dist/server/query/converter.js.map +1 -0
  127. package/dist/server/query/index.d.ts +5 -0
  128. package/dist/server/query/index.d.ts.map +1 -0
  129. package/dist/server/query/index.js +5 -0
  130. package/dist/server/query/index.js.map +1 -0
  131. package/dist/server/shadow/config.d.ts +147 -0
  132. package/dist/server/shadow/config.d.ts.map +1 -0
  133. package/dist/server/shadow/config.js +162 -0
  134. package/dist/server/shadow/config.js.map +1 -0
  135. package/dist/server/shadow/differ.d.ts +42 -0
  136. package/dist/server/shadow/differ.d.ts.map +1 -0
  137. package/dist/server/shadow/differ.js +66 -0
  138. package/dist/server/shadow/differ.js.map +1 -0
  139. package/dist/server/shadow/generator.d.ts +104 -0
  140. package/dist/server/shadow/generator.d.ts.map +1 -0
  141. package/dist/server/shadow/generator.js +148 -0
  142. package/dist/server/shadow/generator.js.map +1 -0
  143. package/dist/server/shadow/index.d.ts +11 -0
  144. package/dist/server/shadow/index.d.ts.map +1 -0
  145. package/dist/server/shadow/index.js +11 -0
  146. package/dist/server/shadow/index.js.map +1 -0
  147. package/dist/server/shadow/types.d.ts +44 -0
  148. package/dist/server/shadow/types.d.ts.map +1 -0
  149. package/dist/server/shadow/types.js +2 -0
  150. package/dist/server/shadow/types.js.map +1 -0
  151. package/dist/server/types.d.ts +295 -0
  152. package/dist/server/types.d.ts.map +1 -0
  153. package/dist/server/types.js +7 -0
  154. package/dist/server/types.js.map +1 -0
  155. package/dist/server/utils/auth.d.ts +43 -0
  156. package/dist/server/utils/auth.d.ts.map +1 -0
  157. package/dist/server/utils/auth.js +123 -0
  158. package/dist/server/utils/auth.js.map +1 -0
  159. package/dist/server/utils/bulkOperations.d.ts +81 -0
  160. package/dist/server/utils/bulkOperations.d.ts.map +1 -0
  161. package/dist/server/utils/bulkOperations.js +147 -0
  162. package/dist/server/utils/bulkOperations.js.map +1 -0
  163. package/dist/server/utils/chunking.d.ts +96 -0
  164. package/dist/server/utils/chunking.d.ts.map +1 -0
  165. package/dist/server/utils/chunking.js +225 -0
  166. package/dist/server/utils/chunking.js.map +1 -0
  167. package/dist/server/utils/dynamodb.d.ts +41 -0
  168. package/dist/server/utils/dynamodb.d.ts.map +1 -0
  169. package/dist/server/utils/dynamodb.js +83 -0
  170. package/dist/server/utils/dynamodb.js.map +1 -0
  171. package/dist/server/utils/filter.d.ts +152 -0
  172. package/dist/server/utils/filter.d.ts.map +1 -0
  173. package/dist/server/utils/filter.js +270 -0
  174. package/dist/server/utils/filter.js.map +1 -0
  175. package/dist/server/utils/pagination.d.ts +27 -0
  176. package/dist/server/utils/pagination.d.ts.map +1 -0
  177. package/dist/server/utils/pagination.js +56 -0
  178. package/dist/server/utils/pagination.js.map +1 -0
  179. package/dist/server/utils/timestamps.d.ts +31 -0
  180. package/dist/server/utils/timestamps.d.ts.map +1 -0
  181. package/dist/server/utils/timestamps.js +84 -0
  182. package/dist/server/utils/timestamps.js.map +1 -0
  183. package/dist/server/utils/ttl.d.ts +17 -0
  184. package/dist/server/utils/ttl.d.ts.map +1 -0
  185. package/dist/server/utils/ttl.js +62 -0
  186. package/dist/server/utils/ttl.js.map +1 -0
  187. package/dist/server/utils/validation.d.ts +40 -0
  188. package/dist/server/utils/validation.d.ts.map +1 -0
  189. package/dist/server/utils/validation.js +54 -0
  190. package/dist/server/utils/validation.js.map +1 -0
  191. package/dist/shadows/config.d.ts +54 -0
  192. package/dist/shadows/config.d.ts.map +1 -0
  193. package/dist/shadows/config.js +95 -0
  194. package/dist/shadows/config.js.map +1 -0
  195. package/dist/shadows/differ.d.ts +42 -0
  196. package/dist/shadows/differ.d.ts.map +1 -0
  197. package/dist/shadows/differ.js +66 -0
  198. package/dist/shadows/differ.js.map +1 -0
  199. package/dist/shadows/generator.d.ts +63 -0
  200. package/dist/shadows/generator.d.ts.map +1 -0
  201. package/dist/shadows/generator.js +107 -0
  202. package/dist/shadows/generator.js.map +1 -0
  203. package/dist/shadows/index.d.ts +15 -0
  204. package/dist/shadows/index.d.ts.map +1 -0
  205. package/dist/shadows/index.js +17 -0
  206. package/dist/shadows/index.js.map +1 -0
  207. package/dist/shadows/types.d.ts +44 -0
  208. package/dist/shadows/types.d.ts.map +1 -0
  209. package/dist/shadows/types.js +2 -0
  210. package/dist/shadows/types.js.map +1 -0
  211. package/dist/types.d.ts +165 -0
  212. package/dist/types.d.ts.map +1 -0
  213. package/dist/types.js +2 -0
  214. package/dist/types.js.map +1 -0
  215. package/dist/ulid.d.ts +46 -0
  216. package/dist/ulid.d.ts.map +1 -0
  217. package/dist/ulid.js +66 -0
  218. package/dist/ulid.js.map +1 -0
  219. package/package.json +136 -0
  220. package/terraform/README.md +222 -0
  221. package/terraform/examples/advanced/README.md +129 -0
  222. package/terraform/examples/advanced/main.tf +158 -0
  223. package/terraform/examples/advanced/shadow.config.json +35 -0
  224. package/terraform/examples/advanced/variables.tf +28 -0
  225. package/terraform/examples/basic/README.md +53 -0
  226. package/terraform/examples/basic/main.tf +99 -0
  227. package/terraform/examples/basic/variables.tf +17 -0
  228. package/terraform/main.tf +159 -0
  229. package/terraform/outputs.tf +56 -0
  230. package/terraform/variables.tf +59 -0
@@ -0,0 +1,225 @@
1
+ /**
2
+ * チャンク分割ユーティリティ
3
+ *
4
+ * DynamoDBのTransactWriteItemsは最大100アイテムまでしか処理できないため、
5
+ * バルク操作(createMany、updateMany、deleteMany)で大量のレコードを処理する際に
6
+ * チャンク分割が必要となる。
7
+ *
8
+ * 要件: 13.1, 13.2, 13.7, 13.8, 13.9
9
+ */
10
+ import { createLogger } from '../../index.js';
11
+ const logger = createLogger({ service: 'records-lambda' });
12
+ /**
13
+ * DynamoDB TransactWriteItemsの最大アイテム数制限
14
+ *
15
+ * DynamoDBのTransactWriteItemsは最大100アイテムまでしか処理できない。
16
+ * この制限を超える場合は、複数のトランザクションに分割する必要がある。
17
+ *
18
+ * 参考: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html
19
+ */
20
+ export const DYNAMODB_TRANSACT_WRITE_MAX_ITEMS = 100;
21
+ /**
22
+ * バルク操作のチャンクサイズを動的に計算する
23
+ *
24
+ * 各レコードのアイテム数(メインレコード + シャドーレコード)を考慮して、
25
+ * TransactWriteItemsの100アイテム制限内に収まるようにチャンクを分割する。
26
+ *
27
+ * @param records - 処理対象のレコード配列
28
+ * @param getItemCount - 各レコードのアイテム数を計算する関数
29
+ * @returns チャンク分割結果
30
+ * @throws {Error} 単一レコードが100アイテムを超える場合
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * // createMany操作の例
35
+ * const result = calculateChunks(records, (record) => {
36
+ * const shadowCount = calculateShadowCount(record);
37
+ * return 1 + shadowCount; // メイン + シャドー
38
+ * });
39
+ *
40
+ * // updateMany操作の例
41
+ * const result = calculateChunks(records, (record) => {
42
+ * const oldShadowCount = record.__shadowKeys?.length || 0;
43
+ * const newShadowCount = calculateNewShadowCount(record);
44
+ * return 1 + oldShadowCount + newShadowCount; // メイン + 削除 + 追加
45
+ * });
46
+ * ```
47
+ */
48
+ export function calculateChunks(records, getItemCount) {
49
+ const chunks = [];
50
+ const itemCounts = [];
51
+ let currentChunk = [];
52
+ let currentItemCount = 0;
53
+ for (const record of records) {
54
+ const itemCount = getItemCount(record);
55
+ // 単一レコードがDynamoDB制限を超える場合はエラー
56
+ if (itemCount > DYNAMODB_TRANSACT_WRITE_MAX_ITEMS) {
57
+ const errorMsg = `Single record exceeds ${DYNAMODB_TRANSACT_WRITE_MAX_ITEMS} items limit: ${itemCount} items`;
58
+ logger.error('Chunk validation failed', {
59
+ itemCount,
60
+ limit: DYNAMODB_TRANSACT_WRITE_MAX_ITEMS,
61
+ });
62
+ throw new Error(errorMsg);
63
+ }
64
+ // 現在のチャンクに追加するとDynamoDB制限を超える場合、新しいチャンクを開始
65
+ if (currentItemCount + itemCount > DYNAMODB_TRANSACT_WRITE_MAX_ITEMS) {
66
+ if (currentChunk.length > 0) {
67
+ chunks.push(currentChunk);
68
+ itemCounts.push(currentItemCount);
69
+ }
70
+ currentChunk = [record];
71
+ currentItemCount = itemCount;
72
+ }
73
+ else {
74
+ currentChunk.push(record);
75
+ currentItemCount += itemCount;
76
+ }
77
+ }
78
+ // 最後のチャンクを追加
79
+ if (currentChunk.length > 0) {
80
+ chunks.push(currentChunk);
81
+ itemCounts.push(currentItemCount);
82
+ }
83
+ // 詳細なチャンク分割情報をログ出力
84
+ logger.info('Chunk calculation completed', {
85
+ totalRecords: records.length,
86
+ chunkCount: chunks.length,
87
+ itemCounts,
88
+ minItemsPerChunk: itemCounts.length > 0 ? Math.min(...itemCounts) : 0,
89
+ maxItemsPerChunk: itemCounts.length > 0 ? Math.max(...itemCounts) : 0,
90
+ avgItemsPerChunk: itemCounts.length > 0
91
+ ? Math.round(itemCounts.reduce((sum, count) => sum + count, 0) / itemCounts.length)
92
+ : 0,
93
+ });
94
+ return { chunks, itemCounts };
95
+ }
96
+ /**
97
+ * チャンクを順次実行し、結果を集約する
98
+ *
99
+ * 各チャンクを独立したトランザクションとして実行し、1つのチャンクが失敗しても
100
+ * 他のチャンクの処理を継続する(部分成功サポート)。
101
+ *
102
+ * @param chunks - 実行するチャンク配列
103
+ * @param executeChunk - 各チャンクを実行する関数(成功したレコードを返す)
104
+ * @param getRecordId - レコードからIDを取得する関数
105
+ * @returns チャンク実行結果
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * const result = await executeChunks(
110
+ * chunks,
111
+ * async (chunk) => {
112
+ * // TransactWriteItemsでチャンクを実行
113
+ * await dynamoDBClient.send(new TransactWriteItemsCommand({
114
+ * TransactItems: buildTransactItems(chunk)
115
+ * }));
116
+ * return chunk; // 成功したレコードを返す
117
+ * },
118
+ * (record) => record.id
119
+ * );
120
+ * ```
121
+ */
122
+ export async function executeChunks(chunks, executeChunk, getRecordId) {
123
+ const successRecords = [];
124
+ const failedIds = [];
125
+ const errors = [];
126
+ const totalRecords = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
127
+ const executionStartTime = Date.now();
128
+ logger.info('Starting chunk execution', {
129
+ totalChunks: chunks.length,
130
+ totalRecords,
131
+ });
132
+ // 各チャンクを順次実行
133
+ for (let i = 0; i < chunks.length; i++) {
134
+ const chunk = chunks[i];
135
+ const chunkStartTime = Date.now();
136
+ try {
137
+ logger.debug(`Executing chunk ${i + 1}/${chunks.length}`, {
138
+ chunkIndex: i,
139
+ recordCount: chunk.length,
140
+ });
141
+ // チャンクを実行
142
+ const successfulRecords = await executeChunk(chunk);
143
+ successRecords.push(...successfulRecords);
144
+ const chunkDuration = Date.now() - chunkStartTime;
145
+ logger.info(`Chunk ${i + 1}/${chunks.length} succeeded`, {
146
+ chunkIndex: i,
147
+ recordCount: chunk.length,
148
+ durationMs: chunkDuration,
149
+ });
150
+ }
151
+ catch (error) {
152
+ // チャンクが失敗した場合、そのチャンク内のすべてのレコードを失敗として記録
153
+ const chunkDuration = Date.now() - chunkStartTime;
154
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
155
+ const errorCode = getErrorCode(error);
156
+ logger.error(`Chunk ${i + 1}/${chunks.length} failed`, {
157
+ chunkIndex: i,
158
+ recordCount: chunk.length,
159
+ durationMs: chunkDuration,
160
+ error: errorMessage,
161
+ errorCode,
162
+ });
163
+ // チャンク内のすべてのレコードを失敗として記録
164
+ for (const record of chunk) {
165
+ const recordId = getRecordId(record);
166
+ failedIds.push(recordId);
167
+ errors.push({
168
+ id: recordId,
169
+ code: errorCode,
170
+ message: errorMessage,
171
+ });
172
+ }
173
+ }
174
+ }
175
+ const totalExecutionTime = Date.now() - executionStartTime;
176
+ // 実行結果のサマリーをログ出力
177
+ logger.info('Chunk execution completed', {
178
+ totalChunks: chunks.length,
179
+ totalRecords,
180
+ successCount: successRecords.length,
181
+ failedCount: failedIds.length,
182
+ totalExecutionTimeMs: totalExecutionTime,
183
+ avgTimePerChunkMs: chunks.length > 0 ? Math.round(totalExecutionTime / chunks.length) : 0,
184
+ });
185
+ // 部分失敗の場合、詳細なエラー情報をログ出力
186
+ if (failedIds.length > 0) {
187
+ logger.warn('Partial failure detected in chunk execution', {
188
+ totalRecords,
189
+ successCount: successRecords.length,
190
+ failedCount: failedIds.length,
191
+ failureRate: `${Math.round((failedIds.length / totalRecords) * 100)}%`,
192
+ failedIds: failedIds.slice(0, 10), // 最初の10件のみログ出力
193
+ errorSummary: errors.slice(0, 5).map((e) => ({
194
+ id: e.id,
195
+ code: e.code,
196
+ message: e.message.substring(0, 100), // メッセージを100文字に制限
197
+ })),
198
+ });
199
+ }
200
+ return {
201
+ successRecords,
202
+ failedIds,
203
+ errors,
204
+ };
205
+ }
206
+ /**
207
+ * エラーからエラーコードを抽出する
208
+ *
209
+ * @param error - エラーオブジェクト
210
+ * @returns エラーコード
211
+ */
212
+ function getErrorCode(error) {
213
+ if (error && typeof error === 'object') {
214
+ // AWS SDK エラー
215
+ if ('name' in error && typeof error.name === 'string') {
216
+ return error.name;
217
+ }
218
+ // カスタムエラー
219
+ if ('code' in error && typeof error.code === 'string') {
220
+ return error.code;
221
+ }
222
+ }
223
+ return 'TRANSACTION_FAILED';
224
+ }
225
+ //# sourceMappingURL=chunking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunking.js","sourceRoot":"","sources":["../../../src/server/utils/chunking.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * DynamoDB操作ユーティリティ
3
+ */
4
+ import type { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';
5
+ /**
6
+ * DynamoDBクライアントを取得する(シングルトン)
7
+ *
8
+ * @returns DynamoDBDocumentClient
9
+ */
10
+ export declare function getDBClient(): DynamoDBDocumentClient;
11
+ /**
12
+ * 環境変数からテーブル名を取得する
13
+ *
14
+ * @returns DynamoDBテーブル名
15
+ * @throws {ConfigError} TABLE_NAME環境変数が未設定の場合
16
+ */
17
+ export declare function getTableName(): string;
18
+ /**
19
+ * レコードから__shadowKeysを除外する
20
+ *
21
+ * @param record - DynamoDBレコード
22
+ * @returns __shadowKeysを除外したレコード
23
+ */
24
+ export declare function removeShadowKeys(record: Record<string, unknown>): Record<string, unknown>;
25
+ /**
26
+ * data属性からレコードを抽出し、__shadowKeysを除外する
27
+ *
28
+ * @param item - DynamoDBアイテム(PK, SK, data構造)
29
+ * @returns クリーンなレコード
30
+ */
31
+ export declare function extractCleanRecord(item: Record<string, unknown>): Record<string, unknown>;
32
+ /**
33
+ * DynamoDB操作を実行し、権限不足エラーを適切にハンドリングする
34
+ *
35
+ * @param operation - 実行するDynamoDB操作
36
+ * @param operationName - 操作名(ログ用)
37
+ * @returns 操作結果
38
+ * @throws {Error} 権限不足エラーまたはその他のエラー
39
+ */
40
+ export declare function executeDynamoDBOperation<T>(operation: () => Promise<T>, operationName: string): Promise<T>;
41
+ //# sourceMappingURL=dynamodb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamodb.d.ts","sourceRoot":"","sources":["../../../src/server/utils/dynamodb.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAYpE;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,sBAAsB,CAOpD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAQrC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAIzF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGzF;AAED;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAAC,CAAC,EAC9C,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,CAAC,CAAC,CAmBZ"}
@@ -0,0 +1,83 @@
1
+ import { ConfigError, createDynamoDBClient, createLogger } from '../../index.js';
2
+ // ロガーインスタンス
3
+ const logger = createLogger({ service: 'records-lambda' });
4
+ /**
5
+ * DynamoDBクライアントのシングルトンインスタンス
6
+ */
7
+ let dbClient = null;
8
+ /**
9
+ * DynamoDBクライアントを取得する(シングルトン)
10
+ *
11
+ * @returns DynamoDBDocumentClient
12
+ */
13
+ export function getDBClient() {
14
+ if (!dbClient) {
15
+ dbClient = createDynamoDBClient({
16
+ region: process.env.AWS_REGION || process.env.REGION,
17
+ });
18
+ }
19
+ return dbClient;
20
+ }
21
+ /**
22
+ * 環境変数からテーブル名を取得する
23
+ *
24
+ * @returns DynamoDBテーブル名
25
+ * @throws {ConfigError} TABLE_NAME環境変数が未設定の場合
26
+ */
27
+ export function getTableName() {
28
+ const tableName = process.env.TABLE_NAME;
29
+ if (!tableName) {
30
+ throw new ConfigError('TABLE_NAME environment variable is not set');
31
+ }
32
+ return tableName;
33
+ }
34
+ /**
35
+ * レコードから__shadowKeysを除外する
36
+ *
37
+ * @param record - DynamoDBレコード
38
+ * @returns __shadowKeysを除外したレコード
39
+ */
40
+ export function removeShadowKeys(record) {
41
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
42
+ const { __shadowKeys, ...rest } = record;
43
+ return rest;
44
+ }
45
+ /**
46
+ * data属性からレコードを抽出し、__shadowKeysを除外する
47
+ *
48
+ * @param item - DynamoDBアイテム(PK, SK, data構造)
49
+ * @returns クリーンなレコード
50
+ */
51
+ export function extractCleanRecord(item) {
52
+ const data = item.data;
53
+ return removeShadowKeys(data);
54
+ }
55
+ /**
56
+ * DynamoDB操作を実行し、権限不足エラーを適切にハンドリングする
57
+ *
58
+ * @param operation - 実行するDynamoDB操作
59
+ * @param operationName - 操作名(ログ用)
60
+ * @returns 操作結果
61
+ * @throws {Error} 権限不足エラーまたはその他のエラー
62
+ */
63
+ export async function executeDynamoDBOperation(operation, operationName) {
64
+ try {
65
+ return await operation();
66
+ }
67
+ catch (error) {
68
+ // 権限不足エラーの場合、詳細なログを出力
69
+ if (error instanceof Error && error.name === 'AccessDeniedException') {
70
+ logger.error('DynamoDB access denied', {
71
+ errorName: error.name,
72
+ errorMessage: error.message,
73
+ operation: operationName,
74
+ tableName: process.env.TABLE_NAME,
75
+ region: process.env.AWS_REGION || process.env.REGION,
76
+ });
77
+ throw new Error(`Insufficient permissions to access DynamoDB: ${operationName}`);
78
+ }
79
+ // その他のエラーはそのまま再スロー
80
+ throw error;
81
+ }
82
+ }
83
+ //# sourceMappingURL=dynamodb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamodb.js","sourceRoot":"","sources":["../../../src/server/utils/dynamodb.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjF,YAAY;AACZ,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;AAE3D;;GAEG;AACH,IAAI,QAAQ,GAAkC,IAAI,CAAC;AAEnD;;;;GAIG;AACH,MAAM,UAAU,WAAW;IACzB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,QAAQ,GAAG,oBAAoB,CAAC;YAC9B,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM;SACrD,CAAC,CAAC;IACL,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;IAEzC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CAAC,4CAA4C,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAA+B;IAC9D,6DAA6D;IAC7D,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;IACzC,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAA6B;IAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,IAA+B,CAAC;IAClD,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,SAA2B,EAC3B,aAAqB;IAErB,IAAI,CAAC;QACH,OAAO,MAAM,SAAS,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,sBAAsB;QACtB,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,uBAAuB,EAAE,CAAC;YACrE,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE;gBACrC,SAAS,EAAE,KAAK,CAAC,IAAI;gBACrB,YAAY,EAAE,KAAK,CAAC,OAAO;gBAC3B,SAAS,EAAE,aAAa;gBACxB,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;gBACjC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM;aACrD,CAAC,CAAC;YACH,MAAM,IAAI,KAAK,CAAC,gDAAgD,aAAa,EAAE,CAAC,CAAC;QACnF,CAAC;QAED,mBAAmB;QACnB,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * DynamoDB フィルター式生成ユーティリティ
3
+ * FilterExpression の構築とシャドーレコード除外条件の生成
4
+ *
5
+ * 要件: 5.5, 7.1, 12.1-12.12
6
+ */
7
+ /**
8
+ * フィルター演算子
9
+ *
10
+ * 要件: 12.2
11
+ */
12
+ export type FilterOperator = 'eq' | 'lt' | 'lte' | 'gt' | 'gte' | 'starts' | 'ends';
13
+ /**
14
+ * フィルター型
15
+ *
16
+ * 要件: 12.5
17
+ */
18
+ export type FilterType = 'string' | 'number' | 'date' | 'boolean';
19
+ /**
20
+ * パース済みフィルターフィールド
21
+ *
22
+ * 要件: 12.1
23
+ */
24
+ export interface ParsedFilterField {
25
+ /** 実際のフィールド名 */
26
+ field: string;
27
+ /** 演算子 */
28
+ operator: FilterOperator;
29
+ /** データ型 */
30
+ type: FilterType;
31
+ }
32
+ /**
33
+ * フィルター式の構築結果
34
+ */
35
+ export interface FilterExpressionResult {
36
+ /** FilterExpression 文字列 */
37
+ expression: string;
38
+ /** ExpressionAttributeNames マッピング */
39
+ names: Record<string, string>;
40
+ /** ExpressionAttributeValues マッピング */
41
+ values: Record<string, unknown>;
42
+ }
43
+ /**
44
+ * フィルターフィールド名をパースする
45
+ *
46
+ * フォーマット: `フィールド名:オペレータ:型`
47
+ * - オペレータ省略時: eq(デフォルト)
48
+ * - 型省略時: string(デフォルト)
49
+ *
50
+ * 例:
51
+ * - "status" → { field: "status", operator: "eq", type: "string" }
52
+ * - "priority:gte" → { field: "priority", operator: "gte", type: "string" }
53
+ * - "priority:gte:number" → { field: "priority", operator: "gte", type: "number" }
54
+ *
55
+ * 要件: 12.1, 12.3, 12.4
56
+ *
57
+ * @param fieldKey - フィルターフィールド名
58
+ * @returns パース結果
59
+ * @throws Error - 構文エラーの場合
60
+ */
61
+ export declare function parseFilterField(fieldKey: string): ParsedFilterField;
62
+ /**
63
+ * シャドーレコードを除外するフィルター式を生成する
64
+ *
65
+ * シャドーレコードの特徴:
66
+ * - SK に '#' が含まれる(例: "name#value#id#ULID")
67
+ * - 本体レコードは "id#ULID" 形式で '#' が1つのみ
68
+ *
69
+ * 除外条件:
70
+ * - attribute_exists(data) AND NOT contains(SK, '#id#')
71
+ *
72
+ * @returns シャドー除外フィルター式
73
+ */
74
+ export declare function createShadowExclusionFilter(): FilterExpressionResult;
75
+ /**
76
+ * ユーザー指定のフィルター条件から FilterExpression を構築する
77
+ *
78
+ * 注意: この実装は基本的な等価比較のみをサポート
79
+ * より複雑な条件(範囲検索、部分一致など)は将来の拡張として実装可能
80
+ *
81
+ * @param filter - フィルター条件(キー: フィールド名、値: 期待値)
82
+ * @returns フィルター式の構築結果
83
+ */
84
+ export declare function buildFilterExpression(filter: Record<string, unknown>): FilterExpressionResult | null;
85
+ /**
86
+ * 複数のフィルター式を AND 条件で結合する
87
+ *
88
+ * @param filters - 結合するフィルター式の配列
89
+ * @returns 結合されたフィルター式
90
+ */
91
+ export declare function combineFilters(filters: (FilterExpressionResult | null)[]): FilterExpressionResult | null;
92
+ /**
93
+ * フィルター式を DynamoDB Query/Scan パラメータに適用する
94
+ *
95
+ * @param params - DynamoDB Query/Scan パラメータ
96
+ * @param filter - フィルター式
97
+ * @returns フィルター式が適用されたパラメータ
98
+ */
99
+ export declare function applyFilterExpression<T extends Record<string, unknown>>(params: T, filter: FilterExpressionResult | null): T;
100
+ /**
101
+ * 型変換ヘルパー
102
+ *
103
+ * 要件: 12.5
104
+ *
105
+ * @param value - 変換する値
106
+ * @param type - 変換先の型
107
+ * @returns 変換後の値
108
+ */
109
+ export declare function convertType(value: unknown, type: FilterType): string | number | Date | boolean;
110
+ /**
111
+ * レコードが単一のフィルター条件に一致するかチェックする
112
+ *
113
+ * 要件: 12.2, 12.6, 12.8, 12.9
114
+ *
115
+ * @param record - チェック対象レコード
116
+ * @param parsed - パース済みフィルター条件
117
+ * @param value - フィルター値
118
+ * @returns 一致する場合true
119
+ */
120
+ export declare function matchesFilter(record: Record<string, unknown>, parsed: ParsedFilterField, value: unknown): boolean;
121
+ /**
122
+ * レコードがすべてのフィルター条件に一致するかチェックする(AND条件)
123
+ *
124
+ * 要件: 12.9
125
+ *
126
+ * @param record - チェック対象レコード
127
+ * @param parsedFilters - パース済みフィルター条件の配列
128
+ * @returns すべての条件に一致する場合true
129
+ */
130
+ export declare function matchesAllFilters(record: Record<string, unknown>, parsedFilters: Array<{
131
+ parsed: ParsedFilterField;
132
+ value: unknown;
133
+ }>): boolean;
134
+ /**
135
+ * Query最適化が可能かチェックする
136
+ *
137
+ * ソートフィールドと一致し、Query可能な演算子を持つフィルター条件を検出する
138
+ *
139
+ * 要件: 12.7
140
+ *
141
+ * @param sortField - ソート対象フィールド
142
+ * @param parsedFilters - パース済みフィルター条件
143
+ * @returns 最適化可能なフィルター条件(なければnull)
144
+ */
145
+ export declare function findOptimizableFilter(sortField: string, parsedFilters: Array<{
146
+ parsed: ParsedFilterField;
147
+ value: unknown;
148
+ }>): {
149
+ parsed: ParsedFilterField;
150
+ value: unknown;
151
+ } | null;
152
+ //# sourceMappingURL=filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../src/server/utils/filter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEpF;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAElE;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU;IACV,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW;IACX,IAAI,EAAE,UAAU,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAiCpE;AAgBD;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,IAAI,sBAAsB,CAWpE;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,sBAAsB,GAAG,IAAI,CA4B/B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,CAAC,sBAAsB,GAAG,IAAI,CAAC,EAAE,GACzC,sBAAsB,GAAG,IAAI,CA6B/B;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrE,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,sBAAsB,GAAG,IAAI,GACpC,CAAC,CAiBH;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,CAe9F;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,OAAO,GACb,OAAO,CA+BT;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,aAAa,EAAE,KAAK,CAAC;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,GAClE,OAAO,CAET;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,KAAK,CAAC;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,GAClE;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAUtD"}