Fix bin/publish: use correct .env path for rspade_system Fix bin/publish script: prevent grep exit code 1 from terminating script 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
3.4 KiB
Executable File
3.4 KiB
Executable File
SSR Full Page Cache (FPC) Implementation Plan
Overview
Server-side rendered static page caching system using Playwright + Redis. Routes marked with #[Static_Page] auto-generate and serve pre-rendered HTML to unauthenticated users.
Implementation Order
Phase 1: Foundation & Research
- Study
rsx:debugcommand and Playwright script structure - Understand current Dispatch.php flow and route attribute processing
Phase 2: Core Commands
- Create
rsx:ssr_fpc:createcommand (copy fromrsx:debug) - Create Playwright script
generate-static-cache.jsin command's resource directory - Implement exclusive lock
GENERATE_STATIC_CACHEin Playwright script - Strip GET parameters from URL before rendering
- Handle redirect interception (manual redirect mode)
- Capture response: DOM + headers OR redirect location
- Generate cache structure with 30-char ETag (SHA1 of build_key + URL + content)
Phase 3: Storage Layer
- Implement Redis cache with key format:
ssr_fpc:{build_key}:{sha1(url)} - Store JSON:
{url, code, page_dom/redirect, build_key, etag, generated_at} - Add comprehensive error logging to
storage/logs/ssr-fpc-errors.log
Phase 4: Runtime Integration
- Update
Session::__is_fpc_client()with header check:X-RSpade-FPC-Client: 1 - Add header to Playwright script
- Create
#[Static_Page]attribute stub in.vscode/attribute-stubs.php - Modify Dispatch.php to:
- Check for
#[Static_Page]attribute - Verify
!Session::is_active()(unauthenticated only) - Skip FPC if
Session::__is_fpc_client()is true - Check Redis cache, generate if missing (fatal on failure)
- Validate ETag for 304 responses
- Serve with proper cache headers (0s dev, 5min prod)
- Check for
Phase 5: Management & Config
- Create
rsx:ssr_fpc:resetcommand (flush Redisssr_fpc:*keys) - Add config to
config/rsx.php:
'ssr_fpc' => [
'enabled' => env('SSR_FPC_ENABLED', false),
'generation_timeout' => 30000, // ms
]
Phase 6: Documentation
- Create
app/RSpade/man/ssr_fpc.txtwith:- Purpose and usage
- Attribute syntax
- Cache lifecycle
- Bypass headers
- Future roadmap (sitemap, parallelization, external service, shared secret)
- Security considerations
Phase 7: Testing
- Test simple static page generation and serving
- Test redirect caching and serving
- Test ETag validation (304 responses)
- Test authenticated user bypass
- Test cache invalidation on build_key change
Key Technical Decisions
Redis Cache Key
Format: ssr_fpc:{build_key}:{sha1(request_path)}
- Auto-invalidates on deployment (build_key changes)
- URL hash prevents key collisions
- GET params stripped before hashing
ETag
First 30 chars of SHA1(build_key + url + content)
FPC Client Header
X-RSpade-FPC-Client: 1
Session Check
Session::is_active() (not RsxAuth::check())
Redirect Handling
Cache first 302, don't follow
Cache TTL
Indefinite (Redis LRU handles eviction)
Future Roadmap (Not in Initial Implementation)
- Option for
rsx:ssr_fpc:create --from-sitemaprather than a specific url - Shared, private, automatic key for the fpc runner, so the fpc headers are only recognized by the server itself
- The same should be done for
rsx:debug
- The same should be done for
- External service to generate the fpc renderings
- Parallelization
- Programmatic cache reset for things like updating cms or blog posts