@@ -103,7 +103,7 @@ public function login(LoginRequest $request)
103103 */
104104 public function session (Request $ request )
105105 {
106- $ token = $ request ->bearerToken ();
106+ $ token = $ request ->bearerToken ();
107107 $ cacheKey = "session_validation_ {$ token }" ;
108108
109109 // Cache session validation for 5 minutes
@@ -154,8 +154,6 @@ public function logout(Request $request)
154154 /**
155155 * Bootstrap endpoint - combines session, organizations, and installer status.
156156 *
157- * @param Request $request
158- *
159157 * @return \Illuminate\Http\Response
160158 */
161159 public function bootstrap (Request $ request )
@@ -630,11 +628,16 @@ public function getUserOrganizations(Request $request)
630628 $ cacheKey = "user_organizations_ {$ user ->uuid }" ;
631629
632630 // Cache for 30 minutes
633- $ companies = Cache::remember ($ cacheKey , now ()->addMinutes (30 ), function () use ($ user ) {
634- // Optimized query: use join instead of whereHas
631+ $ companies = Cache::remember ($ cacheKey , 60 * 30 , function () use ($ user ) {
635632 return Company::select ([
636633 'companies.uuid ' ,
637634 'companies.name ' ,
635+ 'companies.phone ' ,
636+ 'companies.options ' ,
637+ 'companies.currency ' ,
638+ 'companies.timezone ' ,
639+ 'companies.status ' ,
640+ 'companies.type ' ,
638641 'companies.owner_uuid ' ,
639642 'companies.created_at ' ,
640643 'companies.updated_at ' ,
@@ -643,21 +646,37 @@ public function getUserOrganizations(Request $request)
643646 ->where ('company_users.user_uuid ' , $ user ->uuid )
644647 ->whereNull ('company_users.deleted_at ' )
645648 ->whereNotNull ('companies.owner_uuid ' )
646- ->with (['owner:uuid,company_uuid,name,email ' , 'owner.companyUser:uuid,user_uuid,company_uuid ' ])
649+ ->with ([
650+ 'owner:uuid,company_uuid,name,email ' ,
651+ 'owner.companyUser:uuid,user_uuid,company_uuid ' ,
652+ ])
647653 ->distinct ()
648654 ->get ();
649655 });
650656
657+ /**
658+ * Generate a full ETag representing:
659+ * - all org UUIDs
660+ * - all org updated_at timestamps
661+ * - count of organizations
662+ */
663+ $ etagPayload = $ companies ->map (function ($ company ) {
664+ return $ company ->uuid . ': ' . $ company ->updated_at ;
665+ })->join ('| ' );
666+
667+ // Add count to ETag (if orgs added/removed)
668+ $ etagPayload .= '|count: ' . $ companies ->count ();
669+ $ etag = sha1 ($ etagPayload );
670+
651671 return Organization::collection ($ companies )
652672 ->response ()
653- ->header ('Cache-Control ' , 'private, max-age=1800 ' ); // 30 minutes
673+ ->setEtag ($ etag )
674+ ->header ('Cache-Control ' , 'private, max-age=1800, must-revalidate ' );
654675 }
655676
656677 /**
657678 * Clear user organizations cache (call when org changes).
658679 *
659- * @param string $userUuid
660- *
661680 * @return void
662681 */
663682 public static function clearUserOrganizationsCache (string $ userUuid )
0 commit comments