Blame

5f0635 Claude (Dev) 2026-03-13 06:10:21
[mcp] Add P2-1 DynamoDB tables summary
1
---
2
category: reference
3
tags:
4
- P2
5
- dynamodb
6
- infrastructure
7
last_updated: 2026-03-13
8
---
9
10
# P2-1: DynamoDB Tables — Summary
11
12
## Status: Complete
13
14
## Acceptance Criteria
15
16
- [x] Users table: create, read, update by ID; lookup by (oauth_provider, oauth_provider_sub)
17
- [x] Wikis table: create, read, update, delete by (owner_id, wiki_slug); list by owner
18
- [x] ACLs table: create, read, delete by (wiki_id, grantee_id); list by wiki
19
- [x] PITR enabled on all tables
20
- [x] Unit tests pass with moto (22/22)
21
- [ ] Integration test: CRUD against real DynamoDB (not run — `pulumi up` deferred per task spec)
22
23
## Files Changed
24
25
- `infra/components/dynamodb.py` — Pulumi `DynamoDbComponent` with 3 tables + GSI
26
- `infra/__main__.py` — import + instantiation appended at end (no conflicts with P1-5/P1-6)
27
- `app/models/__init__.py` — package init, re-exports all models
28
- `app/models/user.py``UserModel` (create, get, get_by_oauth, update)
29
- `app/models/wiki.py``WikiModel` (create, get, update, delete, list_by_owner)
30
- `app/models/acl.py``AclModel` (create, get, delete, list_by_wiki)
31
- `tests/test_dynamodb.py` — 22 unit tests with moto
32
33
## Design Decisions
34
35
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.
36
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).
37
3. **ACL wiki_id is a composite string** (`owner_id:wiki_slug`), matching the data model comment "owner_id + wiki_slug".
38
4. **ACL create is an upsert** — re-granting a role overwrites the previous entry (no conditional write). This is intentional for role changes.
39
5. **Wiki and User creates use conditional writes** to prevent duplicates.
40
6. **PAY_PER_REQUEST billing** for dev (no capacity planning needed).
41
7. **All resources tagged** with `project: wikibot-io`, `environment: dev`.
42
8. **Plain boto3, no ORM** — models accept a `dynamodb_resource` parameter for dependency injection (used by moto in tests).
43
44
## Test Results
45
46
```
47
22 passed in 15.19s
48
```
49
50
All CRUD operations, GSI queries, conditional writes, error cases, and upsert behavior verified.
51
52
## Pulumi Preview
53
54
Preview shows 3 new DynamoDB tables + 1 component resource, no conflicts with existing infrastructure.
55
56
## Branch
57
58
`feat/P2-1-dynamodb` — 1 commit, not pushed.