Commit Graph

379 Commits

Author SHA1 Message Date
daddy cf17f29799 feat(economy): creator payout request models, migration, and API 2026-09-15 20:43:22 +00:00
daddy 71e741b5f9 Merge branch 'agent/bc90d3f481b4-purchase-escrow-service' into main
checkpoint / checkpoint (push) Successful in 5m41s
2026-09-15 20:41:15 +00:00
daddy 5e1a3bb16e feat(marketplace): purchase service with atomic escrow, 30/70 fee splitting and refunds 2026-09-15 20:41:07 +00:00
daddy 46cd5d6c95 Merge branch 'agent/f51c7d95e237-marketplace-listings-api' into main
checkpoint / checkpoint (push) Successful in 5m31s
2026-09-15 20:36:33 +00:00
daddy 90cc736d37 feat(marketplace): add marketplace listings API and catalog items CRUD 2026-09-15 20:09:07 +00:00
daddy 18306c72e0 Merge branch 'agent/166836d55365-marketplace-models' into main
checkpoint / checkpoint (push) Successful in 5m21s
2026-09-15 19:58:37 +00:00
daddy 0b7f407ad2 Implement CatalogItem, MarketplaceListing, Purchase, CreatorBalance models and Alembic migration 0013 (task 166836d55365) 2026-09-15 19:58:32 +00:00
daddy 30698a77d6 Merge branch 'agent/575fd14b5360-payment-provider-endpoints' into main
checkpoint / checkpoint (push) Successful in 5m19s
2026-09-15 19:56:31 +00:00
daddy 2b78729e6b Implement PaymentProvider interface, NoopPaymentProvider, and purchase/confirm endpoints (task 575fd14b5360) 2026-09-15 19:56:24 +00:00
daddy c9a8c4dfb2 Merge branch 'agent/909e3e9a59af-wallet-service-api' into main
checkpoint / checkpoint (push) Successful in 5m16s
2026-09-15 19:54:12 +00:00
daddy d2bf0e9118 Implement WalletService with atomic credit/debit, row locking, and wallet/transactions API (task 909e3e9a59af) 2026-09-15 19:54:03 +00:00
daddy 80cbcd334b Merge branch 'agent/8343bc0a730f-wallet-models' into main
checkpoint / checkpoint (push) Successful in 5m16s
2026-09-15 19:50:57 +00:00
daddy 64dd8b5f09 Implement wallet and transaction ledger models and Alembic migration (task 8343bc0a730f) 2026-09-15 19:50:53 +00:00
daddy 430042c585 Merge branch 'agent/909744ff1eee-godot-groups-ui' into main
checkpoint / checkpoint (push) Successful in 5m13s
2026-09-15 19:40:53 +00:00
daddy 8e54fee03d Implement Godot groups UI with browse, create, group page, and role management (task 909744ff1eee) 2026-09-15 19:40:41 +00:00
daddy 5b993aa358 Merge branch 'agent/121de83d3be8-godot-profile-ui' into main
checkpoint / checkpoint (push) Successful in 5m10s
2026-09-15 19:38:05 +00:00
daddy 9b381a2b50 Implement Godot profile page UI with bio editing, privacy controls, favorites, and friends (task 121de83d3be8) 2026-09-15 19:37:50 +00:00
daddy a3f895aa19 Merge branch 'agent/9b05df0c6869-godot-chat-ui' into main
checkpoint / checkpoint (push) Successful in 5m9s
2026-09-15 19:35:25 +00:00
daddy 484b455e44 Implement Godot chat UI with DMs, world chat, real-time WebSocket receipt, and reporting (task 9b05df0c6869) 2026-09-15 19:35:13 +00:00
daddy 056e5c9f86 Merge branch 'agent/af249a67f693-godot-friends-presence-ui' into main
checkpoint / checkpoint (push) Successful in 5m9s
2026-09-15 19:32:46 +00:00
daddy e112467b53 Implement Godot friends & presence UI (task af249a67f693) 2026-09-15 19:32:35 +00:00
daddy df75e87885 Merge branch 'agent/264d84d07f28-godot-social-client' into main
checkpoint / checkpoint (push) Successful in 5m9s
2026-09-15 19:25:47 +00:00
daddy 246b7ac996 Implement Godot API client with REST social helpers and WebSocket gateway client (task 264d84d07f28) 2026-09-15 19:25:27 +00:00
daddy 21397b710a Merge branch 'agent/062e441c1419-ws-gateway' into main
checkpoint / checkpoint (push) Successful in 5m6s
2026-09-15 18:58:33 +00:00
daddy e5bcd61ee4 Implement real-time WebSocket gateway for presence, DM, and world chat (US-4, US-2) 2026-09-15 18:58:19 +00:00
daddy 4fc297be43 Merge branch 'agent/39df5555656f-world-chat' into main
checkpoint / checkpoint (push) Successful in 4m59s
2026-09-15 17:55:56 +00:00
daddy 39a971f00e Implement in-experience (world/room) chat endpoints and pub/sub hook (US-4) 2026-09-15 17:55:47 +00:00
daddy d3389a9f48 Merge branch 'agent/8aaf7c48d376-reports' into main
checkpoint / checkpoint (push) Successful in 4m49s
2026-09-15 17:31:44 +00:00
daddy 429cf6f46c Implement message reporting endpoint and moderation review queue (US-4)
- POST /api/chat/messages/{message_id}/report for reporting messages with category/reason
- Idempotent duplicate report rejection (409)
- GET /api/moderation/reports for queue listing (restricted to moderators/admins)
- POST /api/moderation/reports/{id}/resolve supporting dismiss, remove, warn, ban actions
- Audit fields (moderator_id, resolved_at, action) recorded on resolution
- Added 9 integration tests in backend/tests/test_chat_reports.py (all passing)
2026-09-15 17:31:43 +00:00
daddy 01a5520c20 Merge branch 'agent/5645c26acd5c-public-profile' into main
checkpoint / checkpoint (push) Successful in 4m36s
2026-09-15 17:18:29 +00:00
daddy 0b525d6996 Add public profile view endpoint: favorites, friends, privacy enforcement (US-3)
- Implemented GET /api/profile/{user_id} in backend/app/routers/profiles.py
- Server-side privacy enforcement for profile_visibility, favorites_visibility, and friends_list_visibility
- Block relationships enforce restricted view (no bio, empty favorites, empty friends)
- Non-friends restricted when profile_visibility or sections set to friends-only
- Asset public check for avatar in restricted view
- No private user fields leaked (email, password excluded)
- Added 7 integration tests in backend/tests/test_profile.py covering all privacy and block permutations

Independently verified: 26/26 profile tests passing.
2026-09-15 17:18:28 +00:00
daddy eacdeb5b46 Merge branch 'agent/d6b3f928e9ad-dm-chat' into main
checkpoint / checkpoint (push) Successful in 4m30s
2026-09-15 16:56:42 +00:00
daddy 8b17c17137 Add DM chat send/list endpoints: filter, rate limit, conversations (US-4)
Implements direct-message (DM) chat send and history endpoints:
- Migration 0011_add_dm_last_read.py (last_read_at on conversation_participants)
- Models updated in backend/app/models/chat.py
- Router in backend/app/routers/chat_dm.py:
  - POST /api/chat/dm/{user_id}/messages (send DM, filtered via TextFilter, rate-limited via Redis)
  - GET  /api/chat/dm/{user_id}/messages (paginated history, updates last_read_at)
  - GET  /api/chat/dm/conversations (conversations list, last message, unread count)
- Blocks enforced in both directions (cannot send to/from blocked users)
- Self-messaging prevented, peer exist check, auth required
- Integration tests in backend/tests/test_chat_dm.py

Independently re-verified: 14/14 new DM chat tests pass,
272/272 full backend regression suite passes with zero regressions.
2026-09-15 16:56:13 +00:00
daddy 24024a3463 Merge branch 'agent/86f6ef19b352-profile-model' into main
checkpoint / checkpoint (push) Successful in 4m8s
2026-09-15 16:44:16 +00:00
daddy 0a0dde3d50 Add Profile model + migration + own-profile endpoints (US-3)
Implements user profile data model and own-profile management endpoints:
- Profile and ProfileFavorites models in backend/app/models/profile.py
- Migration 0010_add_profile_tables.py (profiles, profile_favorites)
- Endpoints in backend/app/routers/profiles.py:
  - GET  /api/profile/me (own profile with default fallback)
  - PUT  /api/profile/me (upsert bio, avatar_asset_id, privacy settings)
  - GET  /api/profile/me/favorites (list favorite world IDs)
  - PUT  /api/profile/me/favorites (replace favorite world IDs)
- Fixes values_callable on Asset.asset_type ENUM in app/models/asset.py
- Added test_profile.py covering auth, validation, favorites, privacy

Independently re-verified: 19/19 new profile tests pass,
258/258 full backend regression suite passes with zero regressions.
2026-09-15 16:44:00 +00:00
daddy abd05b266d Merge branch 'agent/8bc166bd983b-friends-router' into main
checkpoint / checkpoint (push) Successful in 3m57s
2026-09-15 16:28:31 +00:00
daddy 11c4810231 Add Friends & follow API router: requests, accept/decline, follow, block
Implements docs/planning/social.md US-1's API layer on top of the
merged Friendship/Follow/Block models (app/models/social.py):

- POST/GET /api/friends/requests, POST .../accept, POST .../decline
- DELETE /api/friends/{user_id} (unfriend)
- POST/DELETE /api/friends/{user_id}/follow, GET /api/friends/following
- POST/DELETE /api/friends/{user_id}/block, GET /api/friends/blocked
- GET /api/friends (mutual friends list)

All endpoints require JWT auth. Requests are scoped to caller (no
cross-account enumeration); duplicate/self requests are rejected
idempotently; block clears mutual friendship and follow in both directions.

Independently re-verified: 19/19 new unit/integration tests pass,
239/239 full backend test suite passes with zero regressions.
2026-09-15 16:28:09 +00:00
daddy e2c8671c57 Groups API (CRUD, join/leave, roles, group page)
checkpoint / checkpoint (push) Successful in 3m29s
Full CRUD + membership lifecycle on top of the merged Group/GroupMember
models: create/get/update/delete, join (idempotent)/leave (owner must
transfer first), role-set (owner-only, rejects setting role=owner --
must use /transfer), ownership transfer (exactly-one-owner invariant:
promotes new owner, demotes old to admin). Group page member list uses
an explicit allowlisted schema, no private user fields leak.

Independently re-verified: 220/220 backend tests, transfer/leave/
role-set authorization logic read directly and confirmed sound.
2026-09-15 12:11:42 +00:00
daddy f6c55d888f Add Groups API router: create/join/leave, roles, transfer, group page
Implements docs/planning/social.md US-5's API layer on top of the
already-merged Group/GroupMember models (app/models/groups.py):

- POST/GET /api/groups, GET/PATCH/DELETE /api/groups/{id}
- POST .../join (idempotent), .../leave (owner must transfer first)
- POST .../members/{user_id}/role (owner-only, admin/member),
  .../transfer (owner-only, demotes prior owner to admin)

Group page member list is a dedicated schema (user_id/username/role/
joined_at) so no private User fields leak. 27 new tests cover
authorization boundaries, idempotency, and exactly-one-owner invariants;
full backend suite (220 tests) passes with zero regressions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QFSPt6rX1gwZmcr2HEfvzg
2026-09-15 01:09:29 +00:00
daddy eac6cf81ef Text filtering service + profanity config
checkpoint / checkpoint (push) Successful in 2m56s
TextFilter protocol + ListBasedTextFilter: normalized (case-fold +
leetspeak/lookalike substitution, non-alnum stripped) substring matching
against a configurable JSON term list, with an index map so matched spans
in normalized text translate back to the original text for redaction.
Supports both redact and reject modes. No external service dependency;
the protocol itself is the extension point for a future third-party
provider. Standalone service module, not yet wired into any endpoint
(sibling tasks own that).

Independently re-verified: 193/193 backend tests, no regressions.
2026-09-15 01:02:00 +00:00
daddy 10a431e7a1 Merge branch 'main' into verify-4daac3f1cfba 2026-09-15 00:37:58 +00:00
daddy 0b3622d6b3 Group + membership models + migration
checkpoint / checkpoint (push) Successful in 2m55s
groups (owner SET NULL -- a group is a durable community, not
single-owner content, survives owner deletion) and group_members
(owner/admin/member role, unique group_id+user_id, CASCADE both FKs).
Models/migration only, no API endpoints (sibling task).

Independently re-verified: migration round-trip, schema inspected
directly (FKs/constraints/indexes match spec), 170/170 backend tests.
2026-09-15 00:37:47 +00:00
daddy eb2328b427 Merge branch 'main' into verify-ff065522ba55 2026-09-15 00:35:40 +00:00
daddy 55f849f221 Reusable named rate-limiting dependency (extend existing in-process limiter)
checkpoint / checkpoint (push) Successful in 2m48s
Generalizes app/rate_limit.py's SlidingWindowLimiter pattern (deliberately
in-process, no Redis -- this backend runs single-worker per that file's
own documented reasoning) into a named-limit factory: rate_limit(name,
max_hits=, window_seconds=) returns a FastAPI dependency, reusing the
existing 429+Retry-After behavior and RATE_LIMIT_ENABLED flag. Used by
chat-send/report endpoints (sibling tasks). auth_rate_limit itself
untouched; reset_all() generalized to cover every registered limiter.

Independently re-verified: 164/164 backend tests, no regressions.
2026-09-15 00:35:28 +00:00
daddy 600261dba2 Merge branch 'main' into verify-9eaf37ab424c 2026-09-15 00:33:52 +00:00
daddy c256fb2334 tests/conftest.py: derive the hermetic-bootstrap compose project/ports per checkout
checkpoint / checkpoint (push) Successful in 2m47s
Hardcoded _COMPOSE_PROJECT="agp-pytest" + fixed ports meant every
concurrent checkout running pytest (e.g. multiple Agent-tool subagents,
each in their own workspace clone) fought over the same Docker Compose
project and host ports -- one run's pytest_unconfigure teardown could
yank the ephemeral Postgres out from under a completely unrelated
concurrent run. Confirmed live running 3 parallel subagents: one hit
"connection was closed in the middle of operation", another independently
hit a transient DeadlockDetectedError from concurrent table truncation on
the same shared container. Same root cause and fix pattern as the
agent_core workspace/Docker-Compose collision documented in project_agp
memory -- derive both the project name and the ports from a hash of the
checkout directory so concurrent checkouts land on different
projects/ports while a single checkout stays stable across repeated runs.
2026-09-15 00:33:46 +00:00
daddy 9334caf533 Add pluggable server-side TextFilter service (social.md §4 US-4)
Deterministic default (ListBasedTextFilter) backed by a configurable JSON
term list, with normalization (case-fold, leetspeak substitutions,
stripped punctuation/spacing between letters) so trivial evasion doesn't
slip through. Supports both reject (blocking) and redact (asterisk
replacement) modes. TextFilter is a Protocol, leaving an explicit
extension point for a future third-party moderation provider.

Standalone module, not wired into any router/endpoint -- sibling chat
tasks depend on this one. No DB/migration work.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2FESCaMXeJpC9gSctiEeD
2026-09-15 00:32:17 +00:00
daddy 712d21e746 Add groups + group_members models and migration
docs/planning/social.md US-5 (task 13). Models + Alembic migration only,
per the sibling-dependency boundary with the Groups API task.

- groups: id, name, description, owner_id (FK users, ON DELETE SET NULL --
  a group is a durable multi-member community, so it and its full roster
  survive the owner deleting their account; the API task handles surfacing
  an ownerless group for reassignment).
- group_members: group_id/user_id (both FK, ON DELETE CASCADE -- pure
  join-table rows with no meaning without either side), role
  (owner/admin/member native enum, default member), joined_at, unique
  constraint on (group_id, user_id).
- User gets owned_groups / group_memberships relationships.
- tests/conftest.py TEST_TABLES updated for truncation between tests.
- New tests/test_group_models.py: role assignment, unique-membership
  rejection, group-delete cascade, member-delete cascade, and owner-delete
  SET NULL survival -- all verified against real Postgres.

Verified: upgrade/downgrade/upgrade round-trip, \d-inspected schema matches
spec (FKs, cascade behavior, unique constraint, indexes), full backend
suite 166 passed / 0 regressions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2FESCaMXeJpC9gSctiEeD
2026-09-15 00:28:46 +00:00
daddy de2d431571 Generalize rate_limit.py into a reusable named-limit dependency
Adds rate_limit(name, max_hits=, window_seconds=) as a factory for FastAPI
dependencies, generalizing the auth_rate_limit pattern for future endpoints
(chat send, message report) without touching auth_rate_limit's own behavior.
Reuses SlidingWindowLimiter for counting and the existing 429 + Retry-After
response, and respects RATE_LIMIT_ENABLED the same way auth_rate_limit does.
reset_all() now clears every registered limiter (auth's plus any named ones),
so the conftest autouse fixture keeps working for sibling tasks automatically.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2FESCaMXeJpC9gSctiEeD
2026-09-15 00:26:48 +00:00
daddy f40940a491 Chat data models + migration (conversations, messages, reports)
checkpoint / checkpoint (push) Successful in 2m47s
conversations (denormalized ordered user_a/user_b pair + check constraint
for cheap uniqueness, plus a real conversation_participants join table
for future >2-party support), messages (nullable conversation_id/world_id/
room_id, sender SET NULL to survive account deletion, room_id correctly
FKs into world_rooms), message_reports (SET NULL on message/reporter/
moderator -- audit trail survives deletion, matching the existing
WorldChunkRevision precedent). Models/migration only, no API endpoints.

Independently re-verified: migration round-trip, full schema inspected
directly (FKs/cascade/constraints/indexes all match spec), 160/160
backend tests via the hermetic bootstrap.
2026-09-15 00:22:12 +00:00