Data Model
lk-wiz uses a single-table DynamoDB design for its main data, plus a small dedicated
table for WebSocket connections. Both are PAY_PER_REQUEST, KMS-encrypted, and have
point-in-time recovery (PITR) enabled.
Main table
The main table uses a pk / sk composite key plus two global secondary indexes (GSI1,
GSI2) to serve all access patterns. Entities stored in the table include:
| Entity | Notes |
|---|---|
| User | Identity, approval status, platform role. |
| Workspace | Container for all workspace content. |
| Workspace member | User ↔ workspace link with role (owner/editor/viewer). |
| Idea | Captured idea with status, priority, tags. |
| Post | Draft with lifecycle status and optional schedule. |
| Post version | Immutable snapshot of post content over time. |
| Prompt | Reusable generation instruction template. |
| Example | Reference post used to ground GenAI generation. |
| Publishing slot | Recurring weekly publish time for a workspace. |
| Action | Action request assigned to a workspace member. |
| Yjs document | Persisted collaborative editor state for a post. |
| Quick-capture token | Per-user token for token-based idea capture. |
| Workspace settings | Target audiences and languages for a workspace. |
Connections table
A separate connections table tracks active WebSocket connections for real-time collaboration. Each record carries a TTL so that stale connections are automatically purged by DynamoDB without a cleanup job.
Access patterns
The pk/sk layout and the two GSIs are designed around lk-wiz's access patterns — for
example, listing all ideas or posts in a workspace, resolving a user's workspace
memberships, fetching a post with its versions, and looking up a workspace's publishing
slots. Keeping everything in one table avoids cross-table joins and keeps reads to a single
query per pattern.