docs: rewrite CLAUDE.md with focused architecture guidance#5
docs: rewrite CLAUDE.md with focused architecture guidance#5Cybersoulja wants to merge 2 commits into
Conversation
Replace verbose file/component listings with explanations of how packages connect, request lifecycle, key encoding, share link storage, and dashboard boot sequence. Add missing dev commands (single test, wrangler dev). Remove easily-discoverable file lists and generic advice. https://claude.ai/code/session_01RKoDzdZwpYz1AYzgcnV3Ts
|
Review these changes at https://app.gitnotebooks.com/Cybersoulja/R2-Explorer/pull/5 |
Reviewer's GuideRewrites CLAUDE.md to focus on architecture, request lifecycle, dev/prod wiring between worker and dashboard, and practical commands, while removing verbose file/route listings and generic advice. Sequence diagram for worker request lifecycle and share linkssequenceDiagram
participant U as User
participant D as Dashboard_SPA
participant W as Worker_R2Explorer
participant RO as ReadOnly_middleware
participant AUTH as Auth_middleware
participant H as GetObject_handler
participant S as GetShareLink_handler
participant R2 as R2_bucket
U->>D: Navigate to folder
D->>W: GET /api/buckets/:bucket/:key
W->>RO: apply readonly middleware
RO-->>W: allow (GET/HEAD)
W->>AUTH: basicAuth or cloudflareAccess
AUTH-->>W: set authentication_username
W->>H: GetObject.handle
H->>R2: get object by base64 key
R2-->>H: object data
H-->>D: file listing/contents
U->>W: GET /share/:shareId
W->>S: GetShareLink.handle
S->>R2: get .r2-explorer/sharable-links/:shareId.json
R2-->>S: share metadata
S-->>U: public file response
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Code Review
This pull request refactors CLAUDE.md to provide more concise and structured guidance for Claude Code, including updated command references, a new architecture overview, and refined instructions for adding API endpoints. The review feedback suggests clarifying the route registration order to prevent shadowing and emphasizing the need to validate R2 bucket bindings when accessing them via environment variables.
| ``` | ||
| - **ReadOnly middleware** (`foundation/middlewares/readonly.ts`): blocks all non-GET/HEAD methods when `readonly: true` (the default). | ||
| - **Auth**: either `basicAuth` (Hono built-in) or Cloudflare Access (`@hono/cloudflare-access`). Both are optional and configured via `R2ExplorerConfig`. Auth username is stored in Hono context variables for use by handlers. | ||
| - **Routes**: each endpoint is a class extending `OpenAPIRoute` from Chanfana, one file per endpoint under `src/modules/`. Route registration order matters — the catch-all object routes (`GET /api/buckets/:bucket/:key`, `POST /api/buckets/:bucket/:key`) must be registered last. |
There was a problem hiding this comment.
The instruction that catch-all routes must be registered 'last' is slightly ambiguous. In packages/worker/src/index.ts, some routes (like /api/emails/send) are registered after them. It's more accurate to say they must be registered after more specific routes that share the same path prefix to avoid shadowing.
| - **Routes**: each endpoint is a class extending `OpenAPIRoute` from Chanfana, one file per endpoint under `src/modules/`. Route registration order matters — the catch-all object routes (`GET /api/buckets/:bucket/:key`, `POST /api/buckets/:bucket/:key`) must be registered last. | |
| - **Routes**: each endpoint is a class extending `OpenAPIRoute` from Chanfana, one file per endpoint under `src/modules/`. Route registration order matters — specific routes under a prefix (e.g., `/api/buckets/:bucket/shares`) must be registered before catch-all routes (e.g., `/api/buckets/:bucket/:key`). |
| 1. Create `packages/worker/src/modules/<feature>/myEndpoint.ts` extending `OpenAPIRoute`. | ||
| 2. Define Zod schema for `request.params`, `request.query`, or `request.body`. | ||
| 3. In `handle(c)`, call `this.getValidatedData<typeof this.schema>()` to get typed params. | ||
| 4. Access the R2 bucket via `c.env[bucketName]` — throw `HTTPException(500)` if missing. |
There was a problem hiding this comment.
When accessing the R2 bucket via c.env[bucketName], it is important to validate that bucketName corresponds to an actual R2 bucket binding and not another environment variable or internal binding (like ASSETS). Blindly indexing c.env with a user-provided string from the URL can lead to runtime errors or unintended access to other bindings.
| 4. Access the R2 bucket via `c.env[bucketName]` — throw `HTTPException(500)` if missing. | |
| 4. Access the R2 bucket via `c.env[bucketName]` — validate it is a valid R2 bucket and throw `HTTPException(500)` if missing or invalid. |
$(cat <<'EOF'
Summary
ROOT_FOLDER = "IA=="), request lifecycle, why catch-all routes must be registered last, share link storage in R2Test plan
https://claude.ai/code/session_01RKoDzdZwpYz1AYzgcnV3Ts
EOF
)
Generated by Claude Code
Summary by Sourcery
Rewrite CLAUDE.md to focus on architecture, data flow, and development workflows instead of file listings and low-level implementation details.
Documentation: