-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhandler.go
More file actions
204 lines (181 loc) · 5.7 KB
/
handler.go
File metadata and controls
204 lines (181 loc) · 5.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
package handler
import (
"net/http"
"document-versioning/internal/api"
"document-versioning/internal/store"
"github.com/gin-gonic/gin"
openapi_types "github.com/oapi-codegen/runtime/types"
)
// Handler implements the api.ServerInterface
type Handler struct {
store *store.DocumentStore
}
// NewHandler creates a new Handler
func NewHandler(store *store.DocumentStore) *Handler {
return &Handler{
store: store,
}
}
// Ensure Handler implements ServerInterface
var _ api.ServerInterface = (*Handler)(nil)
// HealthCheck returns the health status of the service
func (h *Handler) HealthCheck(c *gin.Context) {
c.JSON(http.StatusOK, api.HealthResponse{
Status: "ok",
})
}
// CreateDocument creates a new document
// 1. Parse the request body into api.CreateDocumentRequest
// 2. Call h.store.Create() with the name and content
// 3. Return the created document as api.DocumentResponse with status 201
// 4. Handle errors appropriately (400 for bad request, 500 for server error)
func (h *Handler) CreateDocument(c *gin.Context) {
var req api.CreateDocumentRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, api.ErrorResponse{
Error: "invalid request body: " + err.Error(),
})
return
}
if req.Name == "" {
c.JSON(http.StatusBadRequest, api.ErrorResponse{
Error: "name is required",
})
return
}
if req.Content == nil {
c.JSON(http.StatusBadRequest, api.ErrorResponse{
Error: "content is required",
})
return
}
doc, err := h.store.Create(c.Request.Context(), req.Name, req.Content)
if err != nil {
c.JSON(http.StatusInternalServerError, api.ErrorResponse{
Error: "failed to create document: " + err.Error(),
})
return
}
c.JSON(http.StatusCreated, api.DocumentResponse{
Id: doc.ID,
Name: doc.Name,
Content: doc.Content,
CreatedAt: doc.CreatedAt,
})
}
// GetDocument retrieves a document, optionally at a specific version
// 1. The document ID is already parsed by the generated code
// 2. Check if a version query parameter was provided (params.Version)
// 3. If version provided, call h.store.GetAtVersion()
// 4. If no version, call h.store.GetCurrent()
// 5. Return the document as api.DocumentResponse
// 6. Handle errors (404 for not found)
func (h *Handler) GetDocument(c *gin.Context, id openapi_types.UUID, params api.GetDocumentParams) {
var doc *store.Document
var err error
var version int
if params.Version != nil {
doc, err = h.store.GetAtVersion(c.Request.Context(), id, *params.Version)
version = *params.Version
} else {
doc, err = h.store.GetCurrent(c.Request.Context(), id)
version = doc.CurrentVersion
}
if err != nil {
c.JSON(http.StatusNotFound, api.ErrorResponse{
Error: "document not found: " + err.Error(),
})
return
}
c.JSON(http.StatusOK, api.DocumentResponse{
Id: doc.ID,
Name: doc.Name,
Content: doc.Content,
CreatedAt: doc.CreatedAt,
Version: version,
})
}
// UpdateDocument updates a document, creating a new version
// 1. The document ID is already parsed by the generated code
// 2. Parse the request body into api.UpdateDocumentRequest
// 3. Call h.store.Update() with the ID and new content
// 4. Return the updated document as api.DocumentResponse
// 5. Handle errors (404 for not found, 400 for bad request)
func (h *Handler) UpdateDocument(c *gin.Context, id openapi_types.UUID) {
var req api.UpdateDocumentRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, api.ErrorResponse{
Error: "invalid request body: " + err.Error(),
})
return
}
doc, err := h.store.Update(c.Request.Context(), id, req.Content)
if err != nil {
c.JSON(http.StatusNotFound, api.ErrorResponse{
Error: "document not found: " + err.Error(),
})
return
}
c.JSON(http.StatusOK, api.DocumentResponse{
Id: doc.ID,
Name: doc.Name,
Content: doc.Content,
CreatedAt: doc.CreatedAt,
Version: doc.CurrentVersion,
})
}
// ListVersions returns the version history for a document
// 1. The document ID is already parsed by the generated code
// 2. Call h.store.ListVersions()
// 3. Return the version list as api.VersionListResponse
// 4. Handle errors (404 for not found)
func (h *Handler) ListVersions(c *gin.Context, id openapi_types.UUID) {
count, storedVersions, err := h.store.ListVersions(c.Request.Context(), id)
if err != nil {
c.JSON(http.StatusNotFound, api.ErrorResponse{
Error: "document not found: " + err.Error(),
})
return
}
var versions []api.VersionInfo
for _, v := range storedVersions {
versions = append(versions, api.VersionInfo{
Version: v.Version,
CreatedAt: v.CreatedAt,
})
}
c.JSON(http.StatusOK, api.VersionListResponse{
CurrentVersion: count,
DocumentId: id,
Versions: versions,
})
}
// RevertDocument reverts a document to a specific version
// 1. The document ID is already parsed by the generated code
// 2. Parse the request body into api.RevertRequest
// 3. Call h.store.Revert() with the ID and target version
// 4. Return the reverted document as api.DocumentResponse
// 5. Handle errors (404 for not found, 400 for invalid version)
func (h *Handler) RevertDocument(c *gin.Context, id openapi_types.UUID) {
var req api.RevertRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, api.ErrorResponse{
Error: "invalid request body: " + err.Error(),
})
return
}
doc, err := h.store.Revert(c.Request.Context(), id, req.Version)
if err != nil {
c.JSON(http.StatusNotFound, api.ErrorResponse{
Error: "document not found or version invalid: " + err.Error(),
})
return
}
c.JSON(http.StatusOK, api.DocumentResponse{
Id: doc.ID,
Name: doc.Name,
Content: doc.Content,
CreatedAt: doc.CreatedAt,
Version: doc.CurrentVersion,
})
}