-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathregistry-assets-table.ts
More file actions
113 lines (104 loc) · 4.03 KB
/
Copy pathregistry-assets-table.ts
File metadata and controls
113 lines (104 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
* MIT No Attribution
*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import { RemovalPolicy } from 'aws-cdk-lib';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import { Construct } from 'constructs';
/** GSI name for listing every asset of a given kind (REGISTRY.md §3.1). */
export const REGISTRY_KIND_INDEX = 'kind-index';
/**
* Properties for the RegistryAssetsTable construct.
*/
export interface RegistryAssetsTableProps {
/**
* Optional table name override.
* @default - auto-generated by CloudFormation
*/
readonly tableName?: string;
/**
* Removal policy for the table. Registry records are the source of truth for
* what a task may load and are immutable-per-version, so production
* deployments should RETAIN; the construct default stays DESTROY to match the
* rest of the sample stack's dev-first posture.
* @default RemovalPolicy.DESTROY
*/
readonly removalPolicy?: RemovalPolicy;
/**
* Whether to enable point-in-time recovery.
* @default true
*/
readonly pointInTimeRecovery?: boolean;
}
/**
* DynamoDB table backing the agent asset registry (#246; see
* docs/design/REGISTRY.md §3.1 and ADR-018).
*
* Schema:
* - ``pk`` (partition) = ``{kind}#{namespace}/{name}`` — groups every version
* of one asset under a single partition.
* - ``sk`` (sort) = the semver ``version`` string.
*
* A single ``Query`` on ``pk`` returns all versions of an asset (show + resolve;
* resolution ranks by parsed semver in code, since DynamoDB sorts the version
* sort key lexicographically). The ``kind-index`` GSI (partition ``kind``, sort
* ``pk``) powers ``GET /registry/assets?kind=...`` without a table scan.
*
* There is no TTL: registry records are immutable-per-version and audited; a
* ``removed`` status tombstones a record rather than deleting the row (a task
* pinned to it fails closed with ``REMOVED``).
*/
export class RegistryAssetsTable extends Construct {
/**
* The underlying DynamoDB table. Use this to grant access or read the table name.
*/
public readonly table: dynamodb.Table;
constructor(scope: Construct, id: string, props: RegistryAssetsTableProps = {}) {
super(scope, id);
this.table = new dynamodb.Table(this, 'Table', {
tableName: props.tableName,
partitionKey: {
name: 'pk',
type: dynamodb.AttributeType.STRING,
},
sortKey: {
name: 'sk',
type: dynamodb.AttributeType.STRING,
},
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
pointInTimeRecoverySpecification: {
pointInTimeRecoveryEnabled: props.pointInTimeRecovery ?? true,
},
removalPolicy: props.removalPolicy ?? RemovalPolicy.DESTROY,
});
this.table.addGlobalSecondaryIndex({
indexName: REGISTRY_KIND_INDEX,
partitionKey: {
name: 'kind',
type: dynamodb.AttributeType.STRING,
},
sortKey: {
name: 'pk',
type: dynamodb.AttributeType.STRING,
},
// The list endpoint needs kind, namespace, name, version, and status to
// render a summary — a KEYS_ONLY projection would force a second read per
// row, so project everything.
projectionType: dynamodb.ProjectionType.ALL,
});
}
}