Properties
category: reference
tags:
  - P2
  - dynamodb
  - infrastructure
last_updated: 2026-03-13

P2-1: DynamoDB Tables — Summary

Status: Complete

Acceptance Criteria

  • Users table: create, read, update by ID; lookup by (oauth_provider, oauth_provider_sub)
  • Wikis table: create, read, update, delete by (owner_id, wiki_slug); list by owner
  • ACLs table: create, read, delete by (wiki_id, grantee_id); list by wiki
  • PITR enabled on all tables
  • Unit tests pass with moto (22/22)
  • Integration test: CRUD against real DynamoDB (not run — pulumi up deferred per task spec)

Files Changed

  • infra/components/dynamodb.py — Pulumi DynamoDbComponent with 3 tables + GSI
  • infra/__main__.py — import + instantiation appended at end (no conflicts with P1-5/P1-6)
  • app/models/__init__.py — package init, re-exports all models
  • app/models/user.pyUserModel (create, get, get_by_oauth, update)
  • app/models/wiki.pyWikiModel (create, get, update, delete, list_by_owner)
  • app/models/acl.pyAclModel (create, get, delete, list_by_wiki)
  • tests/test_dynamodb.py — 22 unit tests with moto

Design Decisions

  1. Table keys follow the data model exactly. Users PK=id, Wikis PK=owner_id+SK=wiki_slug, ACLs PK=wiki_id+SK=grantee_id.
  2. Single GSI on Users for (oauth_provider, oauth_provider_sub) login lookup. No GSI needed on Wikis (listing by owner is a native PK query) or ACLs (listing by wiki is a native PK query).
  3. ACL wiki_id is a composite string (owner_id:wiki_slug), matching the data model comment "owner_id + wiki_slug".
  4. ACL create is an upsert — re-granting a role overwrites the previous entry (no conditional write). This is intentional for role changes.
  5. Wiki and User creates use conditional writes to prevent duplicates.
  6. PAY_PER_REQUEST billing for dev (no capacity planning needed).
  7. All resources tagged with project: wikibot-io, environment: dev.
  8. Plain boto3, no ORM — models accept a dynamodb_resource parameter for dependency injection (used by moto in tests).

Test Results

22 passed in 15.19s

All CRUD operations, GSI queries, conditional writes, error cases, and upsert behavior verified.

Pulumi Preview

Preview shows 3 new DynamoDB tables + 1 component resource, no conflicts with existing infrastructure.

Branch

feat/P2-1-dynamodb — 1 commit, not pushed.

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9