Skip to content

Conversation

@gocanto
Copy link
Collaborator

@gocanto gocanto commented Jun 25, 2025

Summary by CodeRabbit

  • New Features

    • Introduced structured JSON response formats for profile, experience, projects, social, and talks endpoints.
    • Added support for HTTP caching with ETag headers, enabling more efficient client-side caching and 304 Not Modified responses.
  • Refactor

    • Handlers for profile, experience, projects, social, and talks now use typed payloads and improved response handling with cache validation.
    • Simplified and unified JSON parsing and response logic across endpoints.
    • Replaced raw JSON file reading with a generic JSON parsing utility for cleaner data handling.
  • Chores

    • Updated configuration and fixture files for consistency with new data structures.
    • Removed deprecated response and request handling utilities to streamline codebase.

@coderabbitai
Copy link

coderabbitai bot commented Jun 25, 2025

Caution

Review failed

The pull request is closed.

"""

Walkthrough

This update refactors HTTP handler logic to use typed payload structs and a new response abstraction with ETag-based caching. Handler constructors now require file paths for JSON fixtures. Several new payload struct files are introduced. Legacy response, error, and request handling utilities are removed and replaced by new response logic. The Makefile's ROOT_NETWORK variable is updated. The experience fixture JSON root key is corrected from "date" to "data".

Changes

File(s) Change Summary
Makefile Changed ROOT_NETWORK value from gocanto to oullin_net.
boost/router.go Handler constructors now require JSON file paths as arguments.
handler/profile.go
handler/experience.go
handler/projects.go
handler/social.go
handler/talks.go
Refactored handlers: field contentfilePath, constructors now take file path, use typed payloads, structured response with ETag caching.
handler/payload/profile.go
handler/payload/experience.go
handler/payload/projects.go
handler/payload/social.go
handler/payload/talks.go
Added new payload struct definitions for profile, experience, projects, social, and talks.
handler/response.go
pkg/handler.go
pkg/http/message.go
pkg/request/request.go
pkg/response/response.go
Removed legacy response, error, and request handling utilities.
pkg/http/response.go Added new Response struct with ETag, cache, and JSON response methods, plus internal error helper.
pkg/parser.go Added generic ParseJsonFile function for typed JSON file parsing.
storage/fixture/experience.json Renamed root key "date" to "data".

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Router
    participant Handler
    participant Parser
    participant Response

    Client->>Router: HTTP Request (e.g., /profile)
    Router->>Handler: Call Handler with file path
    Handler->>Parser: ParseJsonFile(filePath)
    Parser-->>Handler: Typed payload struct or error
    Handler->>Response: MakeResponseFrom(version, w, r)
    alt If client cache is valid
        Handler->>Response: HasCache()
        Response-->>Handler: true
        Handler->>Response: RespondWithNotModified()
        Response-->>Client: HTTP 304 Not Modified
    else
        Handler->>Response: RespondOk(payload)
        Response-->>Client: HTTP 200 OK + JSON
    end
Loading

Possibly related PRs

  • HTTP Response Cache #37: Modifies the same handler files and refactors handlers to use typed payloads and new response handling with ETag caching, closely related in implementation.

Poem

A rabbit hops through fields of code,
With structs and JSON neatly bestowed.
Old response tricks now set aside,
ETags and payloads, typed with pride.
From "date" to "data", all aligned—
In oullin_net, new flows designed!
🐇✨
"""


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 738ac44 and 9b7755c.

📒 Files selected for processing (20)
  • Makefile (1 hunks)
  • boost/router.go (5 hunks)
  • handler/experience.go (1 hunks)
  • handler/payload/experience.go (1 hunks)
  • handler/payload/profile.go (1 hunks)
  • handler/payload/projects.go (1 hunks)
  • handler/payload/social.go (1 hunks)
  • handler/payload/talks.go (1 hunks)
  • handler/profile.go (1 hunks)
  • handler/projects.go (1 hunks)
  • handler/response.go (0 hunks)
  • handler/social.go (1 hunks)
  • handler/talks.go (1 hunks)
  • pkg/handler.go (0 hunks)
  • pkg/http/message.go (0 hunks)
  • pkg/http/response.go (1 hunks)
  • pkg/parser.go (1 hunks)
  • pkg/request/request.go (0 hunks)
  • pkg/response/response.go (0 hunks)
  • storage/fixture/experience.json (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@gocanto gocanto force-pushed the feature/cache-response branch from 7de6f96 to 40baa0d Compare June 25, 2025 09:05
@gocanto gocanto marked this pull request as ready for review June 26, 2025 04:07
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (6)
handler/payload/talks.go (1)

15-16: Consider using time.Time for timestamp fields.

The CreatedAt and UpdatedAt fields are currently strings, which may not be optimal for timestamp handling. Consider using time.Time for better type safety and easier date operations.

-	CreatedAt string `json:"created_at"`
-	UpdatedAt string `json:"updated_at"`
+	CreatedAt time.Time `json:"created_at"`
+	UpdatedAt time.Time `json:"updated_at"`

Don't forget to import the time package if you make this change.

handler/payload/profile.go (1)

12-12: Consider email validation for data integrity.

The Email field is currently a plain string. While this is acceptable for a payload struct, consider whether email validation should be implemented at the service layer when processing this data.

handler/payload/projects.go (1)

14-15: Consider using time.Time for timestamp fields.

Similar to other payload structs, the timestamp fields should consider using time.Time instead of strings for better type safety and date handling capabilities.

-	CreatedAt string `json:"created_at"`
-	UpdatedAt string `json:"updated_at"`
+	CreatedAt time.Time `json:"created_at"`
+	UpdatedAt time.Time `json:"updated_at"`
handler/payload/experience.go (2)

14-15: Consider using time.Time for date fields.

The StartDate and EndDate fields would benefit from using time.Time instead of strings for better date handling and validation.

-	StartDate      string `json:"start_date"`
-	EndDate        string `json:"end_date"`
+	StartDate      time.Time `json:"start_date"`
+	EndDate        time.Time `json:"end_date"`

19-19: Consider using slice for Skills field.

The Skills field is currently a single string. Depending on your data structure, you might want to consider using []string to represent multiple skills more clearly.

-	Skills         string `json:"skills"`
+	Skills         []string `json:"skills"`

This would require updating your JSON data format accordingly.

pkg/http/response.go (1)

24-24: Consider making cache duration configurable.

The cache control duration is hardcoded to 1 hour (3600 seconds). Consider making this configurable to allow different caching strategies for different endpoints.

You could add a parameter to MakeResponseFrom or create additional constructor methods:

-func MakeResponseFrom(salt string, writer baseHttp.ResponseWriter, request *baseHttp.Request) *Response {
+func MakeResponseFrom(salt string, writer baseHttp.ResponseWriter, request *baseHttp.Request) *Response {
+	return MakeResponseWithCache(salt, writer, request, 3600)
+}
+
+func MakeResponseWithCache(salt string, writer baseHttp.ResponseWriter, request *baseHttp.Request, maxAge int) *Response {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 738ac44 and 184c56b.

📒 Files selected for processing (20)
  • Makefile (1 hunks)
  • boost/router.go (5 hunks)
  • handler/experience.go (1 hunks)
  • handler/payload/experience.go (1 hunks)
  • handler/payload/profile.go (1 hunks)
  • handler/payload/projects.go (1 hunks)
  • handler/payload/social.go (1 hunks)
  • handler/payload/talks.go (1 hunks)
  • handler/profile.go (1 hunks)
  • handler/projects.go (1 hunks)
  • handler/response.go (0 hunks)
  • handler/social.go (1 hunks)
  • handler/talks.go (1 hunks)
  • pkg/handler.go (0 hunks)
  • pkg/http/message.go (0 hunks)
  • pkg/http/response.go (1 hunks)
  • pkg/parser.go (1 hunks)
  • pkg/request/request.go (0 hunks)
  • pkg/response/response.go (0 hunks)
  • storage/fixture/experience.json (1 hunks)
💤 Files with no reviewable changes (5)
  • handler/response.go
  • pkg/http/message.go
  • pkg/request/request.go
  • pkg/response/response.go
  • pkg/handler.go
🧰 Additional context used
🧬 Code Graph Analysis (3)
boost/router.go (5)
handler/profile.go (1)
  • MakeProfileHandler (15-19)
handler/experience.go (1)
  • MakeExperienceHandler (15-19)
handler/projects.go (1)
  • MakeProjectsHandler (15-19)
handler/social.go (1)
  • MakeSocialHandler (15-19)
handler/talks.go (1)
  • MakeTalksHandler (15-19)
handler/social.go (4)
pkg/http/schema.go (1)
  • ApiError (10-13)
pkg/parser.go (1)
  • ParseJsonFile (9-29)
handler/payload/social.go (1)
  • SocialResponse (3-6)
pkg/http/response.go (2)
  • InternalError (68-73)
  • MakeResponseFrom (18-38)
pkg/http/response.go (1)
pkg/http/schema.go (1)
  • ApiError (10-13)
🔇 Additional comments (16)
pkg/parser.go (1)

9-29: Excellent generic JSON parser implementation!

The function correctly handles generics, provides good error context, and follows Go best practices. The zero value initialization and error wrapping are particularly well done.

storage/fixture/experience.json (1)

3-3: Good standardization of JSON structure.

Renaming the key from "date" to "data" makes more semantic sense for an array of experience records and aligns with the new typed payload structures.

Makefile (1)

23-23: Network configuration updated appropriately.

The addition of quotes and network name change appears to be a proper configuration update for the development environment.

handler/payload/social.go (1)

3-14: Well-structured payload definitions.

The SocialResponse and SocialData structs are properly defined with appropriate JSON tags and field types. This aligns well with the type-safe refactoring approach.

boost/router.go (1)

32-32: Good architectural improvement with parameterized file paths.

The explicit file path parameters make the handlers more flexible and testable. However, there's a potential typo in the handler constructors.

Please verify that the handler constructors don't have a typo. Based on the relevant code snippets, they appear to use filePah instead of filePath:

#!/bin/bash
# Description: Check for potential typo in handler constructor parameter names
# Expected: Should find instances of "filePah" that should likely be "filePath"

echo "Checking for 'filePah' parameter name in handler files:"
rg "filePah" --type go -A 2 -B 2

Also applies to: 42-42, 52-52, 62-62, 72-72

handler/payload/talks.go (1)

1-6: LGTM! Well-structured response payload.

The TalksResponse struct follows the consistent pattern established across other payload files with proper JSON tags and clear field naming.

handler/payload/profile.go (1)

1-6: LGTM! Clean and consistent payload structure.

The ProfileResponse struct follows the established pattern with proper JSON tags and clear field organization.

handler/payload/projects.go (1)

1-6: LGTM! Consistent payload structure.

The ProjectsResponse struct maintains consistency with other payload definitions and has proper JSON tags.

handler/payload/experience.go (1)

1-6: LGTM! Well-structured experience payload.

The ExperienceResponse struct follows the consistent pattern and has proper field organization.

handler/profile.go (2)

22-28: LGTM! Well-implemented generic JSON parsing.

The use of pkg.ParseJsonFile with generic types provides good type safety and the error handling with proper logging is appropriate.


30-42: Excellent caching implementation.

The HTTP caching logic using MakeResponseFrom is well-implemented with proper ETag handling and 304 Not Modified responses. The error handling ensures graceful degradation when JSON marshaling fails.

handler/social.go (1)

30-42: LGTM: Clean HTTP caching implementation.

The new response handling with ETag-based caching is well-implemented. The logic correctly checks for cache hits and responds with 304 Not Modified when appropriate, or returns the full JSON response otherwise.

handler/projects.go (1)

30-42: Consistent implementation with other handlers.

The HTTP response caching logic is consistent with the pattern established in other handlers, which is good for maintainability.

pkg/http/response.go (3)

44-52: LGTM: Clean JSON response handling.

The RespondOk method correctly sets headers, writes the status code, and encodes the payload as JSON. The error handling allows callers to handle JSON encoding failures appropriately.


54-62: LGTM: Proper ETag cache validation.

The HasCache method correctly implements ETag-based cache validation by comparing the client's If-None-Match header with the stored ETag.


18-38: Fix ETag formatting inconsistency.

There's an issue with ETag formatting and trimming. The etag variable in the closure (line 35) uses the original formatted value with quotes, while r.etag stores the trimmed version, causing a mismatch.

Apply this diff to fix the ETag handling:

 func MakeResponseFrom(salt string, writer baseHttp.ResponseWriter, request *baseHttp.Request) *Response {
-	etag := fmt.Sprintf(
-		`"%s"`,
-		strings.TrimSpace(salt),
-	)
+	trimmedSalt := strings.TrimSpace(salt)
+	etag := fmt.Sprintf(`"%s"`, trimmedSalt)
 
 	cacheControl := "public, max-age=3600"
 
 	return &Response{
 		writer:       writer,
 		request:      request,
-		etag:         strings.TrimSpace(etag),
+		etag:         etag,
 		cacheControl: cacheControl,
 		headers: func(w baseHttp.ResponseWriter) {
 			w.Header().Set("Content-Type", "application/json")
 			w.Header().Set("X-Content-Type-Options", "nosniff")
 			w.Header().Set("Cache-Control", cacheControl)
 			w.Header().Set("ETag", etag)
 		},
 	}
 }

Likely an incorrect or invalid review comment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 15

♻️ Duplicate comments (1)
handler/social.go (1)

12-12: Fix typo in field name (same issue as ProfileHandler).

The same typo exists here: filePah should be filePath for consistency and readability.

-	filePah string
+	filePath string
-func MakeSocialHandler(filePah string) SocialHandler {
+func MakeSocialHandler(filePath string) SocialHandler {
-		filePah: filePah,
+		filePath: filePath,
-	data, err := pkg.ParseJsonFile[payload.SocialResponse](h.filePah)
+	data, err := pkg.ParseJsonFile[payload.SocialResponse](h.filePath)

Also applies to: 15-15, 17-17, 22-22

🧹 Nitpick comments (6)
boost/router.go (1)

31-39: Repeated boilerplate – factor into a helper to keep Router lean.

Each method differs only by route, constructor, and fixture filename. A tiny helper would cut the noise:

func (r *Router) mount(path string, factory func(string) handler.ApiHandler, file string) {
    h := factory(filepath.Join(base, file))
    r.Mux.HandleFunc(path, r.PipelineFor(h.Handle))
}

Call it from InitRoutes() instead of keeping five near-identical methods.

Also applies to: 41-49, 51-59, 61-69, 71-79

handler/payload/profile.go (1)

3-14: Structs LGTM – add godoc & consider omitempty tags.

The types map cleanly to JSON. Minor polish:

  1. Add package-level comments for exported structs to satisfy golint.
  2. If zero values are acceptable, append ,omitempty to reduce payload size.

No blockers.

handler/payload/social.go (1)

3-14: Well-formed payload definitions.

Nothing critical spotted. Same godoc / omitempty nit applies here.

handler/payload/projects.go (1)

8-16: Consider time.Time for date fields.

CreatedAt / UpdatedAt as string limit validation and sorting.
Using time.Time (with RFC3339 in JSON) improves type-safety:

-	CreatedAt string `json:"created_at"`
-	UpdatedAt string `json:"updated_at"`
+	CreatedAt time.Time `json:"created_at"`
+	UpdatedAt time.Time `json:"updated_at"`

If consumers rely on plain strings, ignore this.

handler/payload/talks.go (1)

8-17: Consider stronger typing for specific fields.

While the struct design follows good patterns, consider using more specific types:

  • UUID field could use a UUID library type for validation
  • CreatedAt/UpdatedAt could use time.Time for better date/time handling
  • URL field could benefit from url.URL type validation

Current string types work well for JSON serialization but miss opportunities for compile-time type safety and validation.

handler/payload/experience.go (1)

8-20: Consider stronger typing for date and structured fields.

Similar to other payload structs, consider more specific types:

  • StartDate/EndDate could use time.Time or a custom date type
  • UUID field could use a UUID library type
  • Skills field might benefit from a slice type if it represents multiple skills

This would provide better type safety and validation while maintaining JSON serialization compatibility.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 738ac44 and 184c56b.

📒 Files selected for processing (20)
  • Makefile (1 hunks)
  • boost/router.go (5 hunks)
  • handler/experience.go (1 hunks)
  • handler/payload/experience.go (1 hunks)
  • handler/payload/profile.go (1 hunks)
  • handler/payload/projects.go (1 hunks)
  • handler/payload/social.go (1 hunks)
  • handler/payload/talks.go (1 hunks)
  • handler/profile.go (1 hunks)
  • handler/projects.go (1 hunks)
  • handler/response.go (0 hunks)
  • handler/social.go (1 hunks)
  • handler/talks.go (1 hunks)
  • pkg/handler.go (0 hunks)
  • pkg/http/message.go (0 hunks)
  • pkg/http/response.go (1 hunks)
  • pkg/parser.go (1 hunks)
  • pkg/request/request.go (0 hunks)
  • pkg/response/response.go (0 hunks)
  • storage/fixture/experience.json (1 hunks)
💤 Files with no reviewable changes (5)
  • handler/response.go
  • pkg/http/message.go
  • pkg/handler.go
  • pkg/request/request.go
  • pkg/response/response.go
🧰 Additional context used
🧬 Code Graph Analysis (3)
boost/router.go (5)
handler/profile.go (1)
  • MakeProfileHandler (15-19)
handler/experience.go (1)
  • MakeExperienceHandler (15-19)
handler/projects.go (1)
  • MakeProjectsHandler (15-19)
handler/social.go (1)
  • MakeSocialHandler (15-19)
handler/talks.go (1)
  • MakeTalksHandler (15-19)
handler/profile.go (4)
pkg/http/schema.go (1)
  • ApiError (10-13)
pkg/parser.go (1)
  • ParseJsonFile (9-29)
handler/payload/profile.go (1)
  • ProfileResponse (3-6)
pkg/http/response.go (2)
  • InternalError (68-73)
  • MakeResponseFrom (18-38)
pkg/http/response.go (1)
pkg/http/schema.go (1)
  • ApiError (10-13)
🔇 Additional comments (12)
storage/fixture/experience.json (1)

3-3: Key rename looks correct – verify consumers are updated.

"data" now matches the struct tag used in payload.ExperienceResponse. 👍
Double-check that every place previously expecting "date" (tests, clients, docs) has been updated.

pkg/parser.go (1)

9-29: LGTM! Well-designed generic JSON parsing utility.

The function demonstrates good practices with proper error wrapping, clear variable initialization, and helpful comments. The generic type parameter enables type-safe JSON parsing across the codebase.

handler/profile.go (1)

30-42: Excellent implementation of ETag-based caching.

The response handling demonstrates good practices:

  • Proper ETag-based caching with conditional responses
  • Clean separation of cache validation and response generation
  • Appropriate error logging without exposing internal details
  • Structured response handling with the new abstraction
handler/social.go (1)

30-42: Consistent implementation of the new response pattern.

The handler follows the same excellent patterns as ProfileHandler with proper caching, error handling, and structured responses. Good consistency across the refactored handlers.

handler/projects.go (1)

30-42: The caching and response logic looks well-implemented.

The ETag-based caching implementation correctly checks for client cache validity and responds with HTTP 304 when appropriate. The error handling for JSON marshaling is also reasonable - logging the error without returning an API error prevents the handler from failing due to serialization issues.

handler/talks.go (1)

30-42: The refactoring and caching implementation is solid.

The transition to typed payload parsing and ETag-based caching is well-executed. The error handling appropriately logs marshaling errors without failing the entire request.

handler/experience.go (1)

30-42: Excellent refactoring with proper caching implementation.

The move to typed payloads and ETag-based caching significantly improves the handler's reliability and performance. The error handling strategy is appropriate for this use case.

pkg/http/response.go (5)

18-38: Well-designed response constructor with proper caching headers.

The MakeResponseFrom function correctly implements ETag generation and sets appropriate cache control headers. The 1-hour cache duration and public caching are reasonable defaults for static content.


54-62: Correct ETag-based cache validation implementation.

The HasCache() method properly compares the client's If-None-Match header with the server's ETag, following HTTP caching specifications.


44-52: Proper JSON response handling with appropriate headers.

The RespondOk method correctly sets headers, status code, and handles JSON encoding. Using json.NewEncoder().Encode() is the right approach for streaming JSON responses.


64-66: Simple and correct 304 Not Modified response.

The RespondWithNotModified method appropriately sends only the status code for 304 responses, which should not include a response body.


68-73: Verify that the ApiError type is properly imported.

The InternalError function references ApiError but I don't see an explicit import. Ensure this type is available in the current package scope.

#!/bin/bash
# Check if ApiError is defined in this package or properly imported
ast-grep --pattern 'type ApiError struct {
  $$$
}'

# Also check for imports of packages that might contain ApiError
rg -A 3 -B 3 "ApiError"

@gocanto
Copy link
Collaborator Author

gocanto commented Jun 26, 2025

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Jun 26, 2025

✅ Actions performed

Full review triggered.

@gocanto gocanto merged commit ee64505 into main Jun 26, 2025
1 check passed
@gocanto gocanto deleted the feature/cache-response branch June 26, 2025 04:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants