Help us improve
Share bugs, ideas, or general feedback.
From dynamo-expert
Generates language-agnostic repository interfaces (method signatures, input/output types, and entity models) from a DynamoDB table design document. Use when the user has a table design .md file (from dynamodb-table-design skill) and wants to generate the code skeleton for their data access layer. This is Step 3 of a 3-step pipeline: access patterns -> table design -> query interfaces.
npx claudepluginhub walis85300/marketplace --plugin dynamo-expertHow this skill is triggered — by the user, by Claude, or both
Slash command
/dynamo-expert:dynamodb-query-interfacesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill takes a DynamoDB table design document and generates a complete set of repository interfaces: entity types, method signatures, input/output contracts, and key-building utilities. The output is language-agnostic pseudocode that can be directly translated to any language.
Type-safe DynamoDB single-table design with dynamodb-toolbox v2. Provides Entity and Table abstractions for defining key patterns, GSIs, and query operations.
Provides TypeScript patterns for DynamoDB-Toolbox v2: schema/table/entity modeling, .build() workflows, query/scan access patterns, batch/transaction operations, single-table designs with computed keys. For type-safe DynamoDB access layers in TS services.
Generates Repository interfaces and EF Core implementations per aggregate root, with query methods and Unit of Work integration for .NET DDD projects.
Share bugs, ideas, or general feedback.
This skill takes a DynamoDB table design document and generates a complete set of repository interfaces: entity types, method signatures, input/output contracts, and key-building utilities. The output is language-agnostic pseudocode that can be directly translated to any language.
.md file (from dynamodb-table-design or manually written) 1. Access Patterns --> 2. Table Design --> [3. Query Interfaces]
(dynamodb-access- (dynamodb-table- (this skill)
patterns) design)
Input: Table design .md file
Output: Interface definition .md file with pseudocode ready for implementation
Read the table design file. If it doesn't exist or is incomplete, tell the user to run the dynamodb-table-design skill first.
Read reference/language-conventions.md to determine the target language syntax. Ask the user which language they intend to implement in. If they have no preference, use Generic pseudocode.
For each entity in the table design, create a data model type.
Rules:
pk and sk as string fields (these are the DynamoDB key attributes)Template:
// Entity: [Name]
// Description: [from table design]
// PK: [pattern]
// SK: [pattern]
interface [EntityName] {
pk: string
sk: string
[GSI attributes if applicable]
[domain attributes with types]
}
Example (Generic):
// Entity: Order
// Description: A purchase made by a customer
// PK: USER#<userId>
// SK: ORDER#<createdAt>#<orderId>
interface Order {
pk: string // USER#<userId>
sk: string // ORDER#<createdAt>#<orderId>
GSI1PK: optional string // PRODUCT#<productId> (only if indexed)
GSI1SK: optional string // ORDER#<createdAt>#<orderId>
orderId: string // ULID
userId: string
total: number
status: string // PENDING | SHIPPED | DELIVERED | CANCELLED
items: list<OrderItem>
createdAt: string // ISO 8601
updatedAt: optional string // ISO 8601
}
For each entity, generate a function that builds the PK and SK from domain parameters.
Template:
// Builds keys for [EntityName]
// AP references: [list of AP IDs that use this key]
function build[EntityName]Key(params) -> { pk: string, sk: string }
Example:
// Builds keys for Order
// AP references: AP-001, AP-002, AP-010, AP-020
function buildOrderKey({ userId: string, createdAt: string, orderId: string }) -> {
pk: "USER#" + userId,
sk: "ORDER#" + createdAt + "#" + orderId
}
// Builds the prefix key for querying all orders of a user
// AP references: AP-002
function buildOrderCollectionPrefix({ userId: string }) -> {
pk: "USER#" + userId,
skPrefix: "ORDER#"
}
Rules for key builders:
begins_with access patternCreate one repository interface per entity (or per bounded context if the user prefers a unified repository).
Each method in the repository maps to exactly ONE access pattern from the table design.
For each method, define:
Example:
interface OrderRepository {
// AP-001: Get a specific order by orderId
// Operation: Query
// Table/GSI: Table
// Key: ORDER#<orderId> / = ORDER#<orderId>
function getOrderById({ orderId: string }) -> optional Order
// AP-002: List all orders for a user, newest first
// Operation: Query
// Table/GSI: Table
// Key: USER#<userId> / begins_with(ORDER#)
// Params: ScanIndexForward=false, paginated
function listUserOrdersPaginated({
userId: string,
limit: number,
cursor: optional string
}) -> PaginatedResult<Order>
// AP-010: Create a new order
// Operation: TransactWriteItems
// Items:
// 1. Put ORDER in user collection (condition: attribute_not_exists(pk))
// 2. Put ORDER self-record (condition: attribute_not_exists(pk))
// 3. Update ORDER_COUNT +1
function createOrder({
userId: string,
orderId: string,
total: number,
status: string,
items: list<OrderItem>
}) -> Order
}
For write operations that involve multiple items, define the transaction structure:
// AP-010: Create order transaction
transaction CreateOrderTransaction {
items: [
{
operation: Put
entity: Order (user collection)
key: buildOrderKey({ userId, createdAt, orderId })
condition: attribute_not_exists(pk)
},
{
operation: Put
entity: Order (self-record)
key: buildOrderCatalogKey({ orderId })
condition: attribute_not_exists(pk)
},
{
operation: Update
entity: OrderCount
key: buildOrderCountKey({ userId })
update: SET count = count + :inc
values: { ":inc": 1 }
}
]
}
Create a traceability matrix showing that every AP is covered:
| AP ID | Method | Status |
|-------|--------|--------|
| AP-001 | OrderRepository.getOrderById | Covered |
| AP-002 | OrderRepository.listUserOrdersPaginated | Covered |
| AP-010 | OrderRepository.createOrder | Covered |
Every AP MUST have status "Covered". If any AP is "Not Covered", the design has a gap.
Persist the output as a markdown file. Suggest docs/dynamodb/query-interfaces.md or alongside the other files.
Read reference/output-template.md for the exact file structure to use.
When a single Query returns items of different entity types (the power of single-table design), the repository method must:
// AP-003: Get user profile with recent orders
// This is a SINGLE DynamoDB Query that returns heterogeneous items.
// The implementation:
// 1. Queries PK=USER#<userId> with no SK condition (or begins_with(""))
// 2. Iterates results, grouping by SK prefix:
// - SK starts with "USER#" -> User entity
// - SK starts with "ORDER#" -> Order entity
// - SK starts with "BALANCE" -> Balance entity
// 3. Returns the structured result
function getUserProfileWithOrders({ userId: string }) -> {
user: optional User,
orders: list<Order>,
balance: optional Balance
}
.md file.Once the interfaces file is complete, tell the user:
Query interfaces are documented at [file path].
You now have the complete design pipeline:
1. Access Patterns: [path]
2. Table Design: [path]
3. Interfaces: [path]
The next step is implementation. You can use these interfaces as the contract
for your data access layer. Each method comment contains the exact DynamoDB
operation, key construction, and conditions needed.
Recommended implementation order:
1. Entity models (types/interfaces/classes)
2. Key builder functions
3. Repository methods (reads first, then writes)
4. Integration tests against DynamoDB Local or a test table