Stream tenant uploads
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
{"id":"fotospiel-app-auq","title":"Security review checklist: Media pipeline/storage dynamic tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-01-01T16:04:57.616770583+01:00","created_by":"soeren","updated_at":"2026-01-01T16:04:57.616770583+01:00"}
|
||||
{"id":"fotospiel-app-b0h","title":"Security review: trust boundaries/entrypoints mapped","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T16:03:43.175087637+01:00","created_by":"soeren","updated_at":"2026-01-01T16:03:48.799343248+01:00","closed_at":"2026-01-01T16:03:48.799343248+01:00","close_reason":"Completed in codebase (verified)"}
|
||||
{"id":"fotospiel-app-bep","title":"SEC-IO-01 Document PAT revocation/rotation playbook","status":"open","priority":2,"issue_type":"task","created_at":"2026-01-01T15:51:44.568780967+01:00","created_by":"soeren","updated_at":"2026-01-01T15:51:44.568780967+01:00"}
|
||||
{"id":"fotospiel-app-bit","title":"Superadmin control surface roadmap","description":"Roadmap to implement practical superadmin control over tenant admin + guest experience. Tracks lifecycle, moderation, policies, ops health, compliance, audit, announcements, integrations.","status":"open","priority":1,"issue_type":"epic","created_at":"2026-01-01T14:21:01.852988935+01:00","updated_at":"2026-01-01T14:21:01.852988935+01:00","dependencies":[{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-ihd","type":"blocks","created_at":"2026-01-01T14:21:14.445938122+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-wde","type":"blocks","created_at":"2026-01-01T14:21:16.788922347+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-hbt","type":"blocks","created_at":"2026-01-01T14:21:18.300493488+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-arp","type":"blocks","created_at":"2026-01-01T14:21:20.731646568+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-tym","type":"blocks","created_at":"2026-01-01T14:21:23.219093242+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-sbs","type":"blocks","created_at":"2026-01-01T14:21:24.67996941+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-iyc","type":"blocks","created_at":"2026-01-01T14:21:27.027185624+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-097","type":"blocks","created_at":"2026-01-01T14:21:29.668197239+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-lqp","type":"blocks","created_at":"2026-01-01T14:21:31.238481004+01:00","created_by":"soeren"}]}
|
||||
{"id":"fotospiel-app-bit","title":"Superadmin control surface roadmap","description":"Roadmap to implement practical superadmin control over tenant admin + guest experience. Tracks lifecycle, moderation, policies, ops health, compliance, audit, announcements, integrations.","status":"closed","priority":1,"issue_type":"epic","created_at":"2026-01-01T14:21:01.852988935+01:00","updated_at":"2026-01-02T20:18:55.835531926+01:00","closed_at":"2026-01-02T20:18:55.835531926+01:00","close_reason":"Closed","dependencies":[{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-ihd","type":"blocks","created_at":"2026-01-01T14:21:14.445938122+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-wde","type":"blocks","created_at":"2026-01-01T14:21:16.788922347+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-hbt","type":"blocks","created_at":"2026-01-01T14:21:18.300493488+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-arp","type":"blocks","created_at":"2026-01-01T14:21:20.731646568+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-tym","type":"blocks","created_at":"2026-01-01T14:21:23.219093242+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-sbs","type":"blocks","created_at":"2026-01-01T14:21:24.67996941+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-iyc","type":"blocks","created_at":"2026-01-01T14:21:27.027185624+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-097","type":"blocks","created_at":"2026-01-01T14:21:29.668197239+01:00","created_by":"soeren"},{"issue_id":"fotospiel-app-bit","depends_on_id":"fotospiel-app-lqp","type":"blocks","created_at":"2026-01-01T14:21:31.238481004+01:00","created_by":"soeren"}]}
|
||||
{"id":"fotospiel-app-bjd","title":"Checkout refactor: auth/login/register flow alignment","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T16:06:09.920731675+01:00","created_by":"soeren","updated_at":"2026-01-01T16:06:15.500724195+01:00","closed_at":"2026-01-01T16:06:15.500724195+01:00","close_reason":"Completed in codebase (verified)"}
|
||||
{"id":"fotospiel-app-bqm","title":"Paddle catalog sync: unit tests for service + jobs","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T16:01:22.090498843+01:00","created_by":"soeren","updated_at":"2026-01-01T16:01:27.71412122+01:00","closed_at":"2026-01-01T16:01:27.71412122+01:00","close_reason":"Completed in codebase (verified)"}
|
||||
{"id":"fotospiel-app-bxu","title":"Checkout refactor: Stripe/Paddle payment integration + webhooks","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T16:06:32.279485614+01:00","created_by":"soeren","updated_at":"2026-01-01T16:06:37.876950599+01:00","closed_at":"2026-01-01T16:06:37.876950599+01:00","close_reason":"Completed in codebase (verified)"}
|
||||
@@ -66,7 +66,7 @@
|
||||
{"id":"fotospiel-app-jqy","title":"Tenant admin onboarding: Playwright skeleton for welcome flow","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T16:08:11.226297707+01:00","created_by":"soeren","updated_at":"2026-01-01T16:08:16.827679424+01:00","closed_at":"2026-01-01T16:08:16.827679424+01:00","close_reason":"Completed in codebase (verified)"}
|
||||
{"id":"fotospiel-app-ko0","title":"Security review checklist: Webhooks/Billing dynamic tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-01-01T16:04:51.987093237+01:00","created_by":"soeren","updated_at":"2026-01-01T16:04:51.987093237+01:00"}
|
||||
{"id":"fotospiel-app-kry","title":"Paddle catalog sync: add DTO helpers for Paddle product/price responses","status":"open","priority":2,"issue_type":"task","created_at":"2026-01-01T15:58:57.817750548+01:00","created_by":"soeren","updated_at":"2026-01-01T15:58:57.817750548+01:00"}
|
||||
{"id":"fotospiel-app-kso","title":"SEC-MS-02 Streaming upload refactor + tests","status":"open","priority":2,"issue_type":"task","created_at":"2026-01-01T15:53:03.729137616+01:00","created_by":"soeren","updated_at":"2026-01-01T15:53:03.729137616+01:00"}
|
||||
{"id":"fotospiel-app-kso","title":"SEC-MS-02 Streaming upload refactor + tests","description":"Current state (code scan)\n- Guest uploads: App\\\\Http\\\\Controllers\\\\Api\\\\EventPublicController@upload uses Storage::disk()-\u003eputFile (stream-friendly) but still does watermark/thumbnail work inline.\n- Tenant admin uploads: App\\\\Http\\\\Controllers\\\\Api\\\\Tenant\\\\PhotoController@store and @uploadDirect use Storage::disk()-\u003eput($path, file_get_contents(...)) which loads entire file into memory.\n- Photobooth ingest already streams from import disk via readStream -\u003e Storage::disk()-\u003eput($path, $stream).\n- Presigned upload flow is stubbed to a local upload-direct endpoint; no true presigned S3 handling yet.\n- No tenant upload feature tests exist; guest upload tests exist and cover limits/security.\n\nGoal\n- Stream uploads to disk (avoid full in-memory buffers) for tenant-admin upload endpoints and keep behavior consistent across sources.\n\nPlan\n1) Introduce a small streaming upload helper/service\n - New service (e.g. App\\\\Services\\\\Storage\\\\UploadStreamService) that accepts UploadedFile + disk + destination path.\n - Use fopen on UploadedFile::getRealPath (or $file-\u003egetStream()) and Storage::disk($disk)-\u003eput($path, $stream) / writeStream.\n - Always close stream; return stored size and checksum (hash_file on stored path) for asset metadata.\n\n2) Refactor tenant upload endpoints to use streaming\n - Update PhotoController@store and @uploadDirect to use the helper instead of file_get_contents.\n - Use Storage::disk()-\u003eputFileAs (or helper) to preserve deterministic paths without buffering.\n - Keep existing validation, watermark, thumbnail, asset recording, and package usage logic.\n\n3) Optional consistency pass on guest upload\n - Consider routing EventPublicController@upload through the same helper for consistent storage + checksum handling, while keeping current validation/limits.\n\n4) Tests\n - Add Feature tests for tenant upload endpoints:\n - /api/v1/tenant/events/{slug}/photos (store) uploads a fake image and persists Photo + EventMediaAsset with expected path/size.\n - /api/v1/tenant/events/{slug}/upload-direct (presigned) uploads a fake image and stores asset + thumbnail.\n - Ensure existing guest upload tests still pass (no behavioral changes).\n\n5) Safety/ops\n - Verify streaming logic handles empty/invalid files gracefully and still reports errors via ApiError.\n - Keep request-time processing (thumb/watermark) unchanged for now; consider queuing in a follow-up if CPU spikes persist.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T15:53:03.729137616+01:00","created_by":"soeren","updated_at":"2026-01-02T20:51:17.752365339+01:00","closed_at":"2026-01-02T20:51:17.752365339+01:00","close_reason":"Closed"}
|
||||
{"id":"fotospiel-app-kxe","title":"Paddle customer success metrics (tenant ↔ Paddle sync, sandbox seeding, rollout/rollback)","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T16:10:34.454400334+01:00","created_by":"soeren","updated_at":"2026-01-02T17:03:51.48872094+01:00","closed_at":"2026-01-02T17:03:51.48872094+01:00","close_reason":"Closed"}
|
||||
{"id":"fotospiel-app-l3n","title":"Session changes 2025-09-08 (PRP split, PWA scaffolding, Filament resources, API)","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T16:10:18.204088457+01:00","created_by":"soeren","updated_at":"2026-01-01T16:10:23.815135505+01:00","closed_at":"2026-01-01T16:10:23.815135505+01:00","close_reason":"Completed in codebase (verified)"}
|
||||
{"id":"fotospiel-app-l6a","title":"Registration flow fixes: JSON redirect, error clearing, role handling","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T16:07:16.253760139+01:00","created_by":"soeren","updated_at":"2026-01-01T16:07:21.964843904+01:00","closed_at":"2026-01-01T16:07:21.964843904+01:00","close_reason":"Completed in codebase (verified)"}
|
||||
|
||||
Reference in New Issue
Block a user