aeo-optimization
AI Engine Optimization - semantic triples, page templates, content clusters for AI citations
AWS DynamoDB single-table design, GSI patterns, SDK v3 TypeScript/Python
$ npx -y skills add alinaqi/claude-bootstrap --skill aws-dynamodb --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/aws-dynamodbContext preview
The summary Claude sees to decide when to auto-load this skill.
AWS DynamoDB single-table design, GSI patterns, SDK v3 TypeScript/Python
name: aws-dynamodb description: AWS DynamoDB single-table design, GSI patterns, SDK v3 TypeScript/Python when-to-use: When working with DynamoDB tables or AWS SDK data operations user-invocable: false paths: ["**/dynamodb*", "**/dynamo*", "serverless.*", "template.yaml"] effort: medium
DynamoDB is a fully managed NoSQL database designed for single-digit millisecond performance at any scale. Master single-table design and access pattern modeling.
**Sources:** [DynamoDB Docs](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/) | [SDK v3](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/) | [Best Practices](https://aws.amazon.com/blogs/database/single-table-vs-multi-table-design-in-amazon-dynamodb/)
---
**Design for access patterns, not entities. Think access-pattern-first.**
DynamoDB requires you to know your queries before designing your schema. Model around how you'll access data, not how data relates. Single-table design stores multiple entity types in one table using generic key attributes.
---
| Concept | Description | |---------|-------------| | **Partition Key (PK)** | Primary key attribute - determines data distribution | | **Sort Key (SK)** | Optional secondary key for range queries within partition | | **GSI** | Global Secondary Index - alternate partition/sort keys | | **LSI** | Local Secondary Index - same partition, different sort | | **Item** | Single record (max 400 KB) | | **Attribute** | Field within an item |
---
// Instead of entity-specific keys:
// userId, orderId, productId
// Use generic keys that work for all entities:
interface BaseItem {
PK: string; // Partition Key
SK: string; // Sort Key
GSI1PK?: string; // First GSI partition key
GSI1SK?: string; // First GSI sort key
EntityType: string;
// ... entity-specific attributes
}// Users
{ PK: 'USER#123', SK: 'PROFILE', EntityType: 'User', name: 'John', email: 'john@test.com' }
{ PK: 'USER#123', SK: 'ADDRESS#1', EntityType: 'Address', street: '123 Main', city: 'NYC' }
// Orders for user (1:N relationship)
{ PK: 'USER#123', SK: 'ORDER#2024-001', EntityType: 'Order', total: 99.99, status: 'shipped' }
{ PK: 'USER#123', SK: 'ORDER#2024-002', EntityType: 'Order', total: 49.99, status: 'pending' }
// Order details (query by order ID using GSI)
{ PK: 'USER#123', SK: 'ORDER#2024-001', GSI1PK: 'ORDER#2024-001', GSI1SK: 'ORDER', ... }
{ PK: 'ORDER#2024-001', SK: 'ITEM#1', GSI1PK: 'ORDER#2024-001', GSI1SK: 'ITEM#1', productId: 'PROD#456', qty: 2 }
// Products
{ PK: 'PROD#456', SK: 'PRODUCT', EntityType: 'Product', name: 'Widget', price: 29.99 }1. Get user profile → Query PK='USER#123', SK='PROFILE' 2. Get user with addresses → Query PK='USER#123', SK begins_with 'ADDRESS' 3. Get all user orders → Query PK='USER#123', SK begins_with 'ORDER' 4. Get order by ID → Query GSI1, PK='ORDER#2024-001' 5. Get order with items → Query GSI1, PK='ORDER#2024-001' 6. Get product details → Query PK='PROD#456', SK='PRODUCT'
---
npm install @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb
// lib/dynamodb.ts
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';
const client = new DynamoDBClient({
region: process.env.AWS_REGION || 'us-east-1',
// For local development with DynamoDB Local
...(process.env.DYNAMODB_LOCAL && {
endpoint: 'http://localhost:8000',
credentials: { accessKeyId: 'local', secretAccessKey: 'local' }
})
});
// Document client for simplified operations
export const docClient = DynamoDBDocumentClient.from(client, {
marshallOptions: {
removeUndefinedValues: true, // Important: match v2 behavior
convertClassInstanceToMap: true
},
unmarshallOptions: {
wrapNumbers: false
}
});
export const TABLE_NAME = process.env.DYNAMODB_TABLE || 'MyTable';// types/dynamodb.ts
export interface BaseItem {
PK: string;
SK: string;
GSI1PK?: string;
GSI1SK?: string;
EntityType: string;
createdAt: string;
updatedAt: string;
}
export interface User extends BaseItem {
EntityType: 'User';
userId: string;
email: string;
name: string;
}
export interface Order extends BaseItem {
EntityType: 'Order';
orderId: string;
userId: string;
total: number;
status: 'pending' | 'paid' | 'shipped' | 'delivered';
}
// Key builders
export const keys = {
user: (userId: string) => ({
PK: `USER#${userId}`,
SK: 'PROFILE'
}),
userOrders: (userId: string) => ({
PK: `USER#${userId}`,
SKPrefix: 'ORDER#'
}),
order: (userId: string, orderId: string) => ({
PK: `USER#${userId}`,
SK: `ORDER#${orderId}`,
GSI1PK: `ORDER#${orderId}`,
GSI1SK: 'ORDER'
})
};---
import { PutCommand } from '@aws-sdk/lib-dynamodb';
import { docClient, TABLE_NAME } from './dynamodb';
import { User, keys } from './types';
async function createUser(userId: string, data: { email: string; name: string }): Promise<User> {
const now = new Date().toISOString();
const item: User = {
...keys.user(userId),
EntityType: 'User',
userId,
email: data.email,
name: data.name,
createdAt: now,
updatedAt: now
};
await docClient.send(new PutCommand({
TableName: TABLE_NAME,
Item: item,
ConditionExpression: 'attribute_not_exists(PK)' // Prevent overwrite
}));
return item;
}Turn Claude Code into a self-reviewing, test-enforced engineering system that remembers context across sessions — then route work across 13 models from a single dashboard.
Repo: alinaqi/claude-bootstrap
AI Engine Optimization - semantic triples, page templates, content clusters for AI citations
Claude Code Agent Teams - default team-based development with strict TDD pipeline enforcement
Build AI agents with Pydantic AI (Python) and Claude SDK (Node.js)
Latest AI models reference - Claude, OpenAI, Gemini, Eleven Labs, Replicate
Android Kotlin development with Coroutines, Jetpack Compose, Hilt, and MockK testing