docs: update CLAUDE.md testing requirements, architecture, and design system

- CLAUDE.md: add mandatory test coverage rule (all 3 layers required),
  document BYOB shop-aware S3 methods, update test count to 712
- architecture.md: mark MPS-14/15/16 complete, add environment/trial/BYOB
  to feature toggle matrix, add BYOB to S3 storage diagram
- design-system.md: add environment and trial banner components
This commit is contained in:
russell@unturf.com 2026-03-07 19:01:57 -05:00
parent 395e703a20
commit bfe2289313
3 changed files with 40 additions and 6 deletions

View file

@ -20,6 +20,13 @@ Files are NEVER streamed through uwsgi. The server only generates presigned URLs
- **Uploads**: presigned `post` → client uploads directly to Spaces - **Uploads**: presigned `post` → client uploads directly to Spaces
- **Thumbnails**: public CDN URLs with `?ts=` cache busting - **Thumbnails**: public CDN URLs with `?ts=` cache busting
**BYOB (Bring Your Own Bucket)**: Shops can configure their own S3-compatible bucket (`bucket-settings` form section). When enabled, all presigned URLs and CDN references use the shop's bucket. Always use shop-aware request methods in views and templates:
- `request.shop_uploads_client` — S3 client (shop's or MPS default)
- `request.shop_bucket_name` — bucket name (shop's or MPS default)
- `request.shop_cdn_endpoint` — CDN URL (shop's or MPS default)
**NEVER** use `request.app["bucket.secure_uploads"]`, `request.app["bucket.secure_uploads.get_endpoint"]`, or `request.secure_uploads_client` directly in views or templates. These are only used internally by `request_methods.py` as fallbacks.
### Karaoke Pipeline (lib/karaoke.py) ### Karaoke Pipeline (lib/karaoke.py)
Disk-backed vocal isolation pipeline. Downloads media from S3, builds a JSON Disk-backed vocal isolation pipeline. Downloads media from S3, builds a JSON
@ -100,10 +107,12 @@ env/bin/py.test make_post_sell/tests/test_functional.py # Functional tests
env/bin/py.test --cov=make_post_sell.models.cart --cov-report=term-missing make_post_sell/tests/test_models.py::TestCart env/bin/py.test --cov=make_post_sell.models.cart --cov-report=term-missing make_post_sell/tests/test_models.py::TestCart
``` ```
### Current Coverage ### Current Coverage (712 tests)
- Cart model unit tests cover critical business logic like `requires_payment` threshold (64 cents) - Cart model unit tests cover critical business logic like `requires_payment` threshold (64 cents)
- Integration tests verify the original AttributeError defect fix for free coupon checkout - Shop environment, trial, and BYOB model properties (TestShopEnvironment, TestShopTrial, TestShopBYOB)
- Functional tests provide end-to-end coverage of cart/checkout/payment flows - Gift card model unit tests (generation, validation, transactions)
- Integration tests verify free coupon checkout, gift card flows, and multi-model interactions
- Functional tests cover cart/checkout/payment, gift card settings, environment settings, bucket settings
## Database Location ## Database Location
@ -260,6 +269,13 @@ Elements that must stay in sync: CTA edit button, download button, comment form
Disabling or removing tests weakens the codebase and is unacceptable. Tests are critical safety nets that prevent regressions. Disabling or removing tests weakens the codebase and is unacceptable. Tests are critical safety nets that prevent regressions.
**MANDATORY TEST COVERAGE**: Every new feature, model property, view handler, or form section MUST have tests across all three layers:
- **Unit tests** (`test_models.py`) — Test new model properties, methods, and business logic in isolation using `mock.patch`. No DB required.
- **Integration tests** (`test_integration.py`) — Test interactions between models, especially multi-model workflows (e.g., cart + coupon + gift card).
- **Functional tests** (`test_functional.py`) — Test through the web interface using `webtest.TestApp`. Cover settings form POSTs, page loads, flash messages, and DB state changes.
If a feature touches all three layers (model + view + template), it needs tests in all three files. No exceptions. Untested code is incomplete code.
**AUTO-PUSH**: When you write new tests to cover new code paths and the full test suite passes, commit and push without asking. Bump GIT_HASH after pushing. **AUTO-PUSH**: When you write new tests to cover new code paths and the full test suite passes, commit and push without asking. Bump GIT_HASH after pushing.
## Post-Work Chores ## Post-Work Chores

View file

@ -161,6 +161,19 @@ mps_page_session (raw rows)
│ Backfill on setup │ │ Backfill on setup │
└─────────────────────┘ └─────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Shop Primary Bucket (BYOB) │
│ (shop.has_primary_s3 — MPS-16) │
│ │
│ When enabled, REPLACES MPS Main Bucket for this shop: │
│ - All presigned URLs use shop's S3 client │
│ - All CDN URLs use shop's cdn_endpoint │
│ - request.shop_uploads_client / shop_bucket_name / │
│ shop_cdn_endpoint fall back to MPS default when off │
│ │
│ Configured via bucket-settings form section │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────┐
│ User Artifact Bucket │ │ User Artifact Bucket │
│ (user.has_s3_bucket) │ │ (user.has_s3_bucket) │
@ -188,6 +201,9 @@ mps_page_session (raw rows)
| Crypto | `shop.monero_*` / `shop.dogecoin_*` | `crypto-settings` | Off | | Crypto | `shop.monero_*` / `shop.dogecoin_*` | `crypto-settings` | Off |
| Gift cards | `shop.gift_card_enabled` | `gift-card-settings` | Off | | Gift cards | `shop.gift_card_enabled` | `gift-card-settings` | Off |
| S3 mirror | `shop.mirror_s3_*` | `mirror-settings` | Off | | S3 mirror | `shop.mirror_s3_*` | `mirror-settings` | Off |
| BYOB (primary S3) | `shop.primary_s3_*` | `bucket-settings` | Off |
| Environment | `shop.environment` | `environment-settings` | 0 (production) |
| Trial | `shop.trial_started_timestamp` | Auto on creation | 21 days |
| Discovery ring | `shop.discovery_ring` | Automatic | Auto-computed | | Discovery ring | `shop.discovery_ring` | Automatic | Auto-computed |
| Subscriptions | `shop.subscription_*` | `ribbon-settings` | Off | | Subscriptions | `shop.subscription_*` | `ribbon-settings` | Off |
@ -209,9 +225,9 @@ mps_page_session (raw rows)
| [MPS-11](tickets/mps-11.md) | Gift Card — Purchase Flow | Complete | | [MPS-11](tickets/mps-11.md) | Gift Card — Purchase Flow | Complete |
| [MPS-12](tickets/mps-12.md) | Gift Card — Redemption at Checkout | Complete | | [MPS-12](tickets/mps-12.md) | Gift Card — Redemption at Checkout | Complete |
| [MPS-13](tickets/mps-13.md) | Gift Card — Shop Admin & Settings | Complete | | [MPS-13](tickets/mps-13.md) | Gift Card — Shop Admin & Settings | Complete |
| [MPS-14](tickets/mps-14.md) | Shop Environment — Dev & Stage Shops | Open | | [MPS-14](tickets/mps-14.md) | Shop Environment — Dev & Stage Shops | Complete |
| [MPS-15](tickets/mps-15.md) | 21-Day Free Trial | Open | | [MPS-15](tickets/mps-15.md) | 21-Day Free Trial | Complete |
| [MPS-16](tickets/mps-16.md) | Bring Your Own Bucket (BYOB) | Open | | [MPS-16](tickets/mps-16.md) | Bring Your Own Bucket (BYOB) | Complete |
## Related Docs ## Related Docs

View file

@ -238,6 +238,8 @@ All components are documented with live examples at `/styleguide`. The styleguid
| Comments | `#comments` | Comment form and list | | Comments | `#comments` | Comment form and list |
| Toggle | `#toggle` | Toggle switches | | Toggle | `#toggle` | Toggle switches |
| Ribbon | `#ribbon` | Shop ribbon banner | | Ribbon | `#ribbon` | Shop ribbon banner |
| Environment Banner | `.environment-banner` | Staging/dev environment indicator |
| Trial Banner | `.trial-banner` | Trial countdown and expiry notice |
| Task Bar | `#taskbar` | Task bar component | | Task Bar | `#taskbar` | Task bar component |
| Layout | `#layout` | Grid layout patterns | | Layout | `#layout` | Grid layout patterns |
| Theme System | `#theme` | Theme toggle and dark mode | | Theme System | `#theme` | Theme toggle and dark mode |