aravind changes

This commit is contained in:
2026-08-25 16:37:05 +05:30
parent cadea4bd92
commit b6f8655909
27 changed files with 5058 additions and 163 deletions

View File

@@ -1,6 +1,7 @@
package httpserver
import (
"context"
"encoding/json"
"io"
"net/http"
@@ -130,7 +131,7 @@ func (s *Server) handleCreate(svc *service.Service) http.HandlerFunc {
writeError(w, s.log, err)
return
}
rec, err := svc.Create(r.Context(), ident, body)
rec, err := s.create(r.Context(), svc, ident, body)
if err != nil {
writeError(w, s.log, err)
return
@@ -139,6 +140,25 @@ func (s *Server) handleCreate(svc *service.Service) http.HandlerFunc {
}
}
// create inserts through the resource's own service, except where creating a
// record has a consequence in another table.
//
// One resource has one: an AI interview is only half of completing an
// interview, and the application it names has to be linked in the same
// transaction — see internal/service/interviews.go for why the server performs
// that write and the caller may not. Routing it here rather than registering a
// second endpoint keeps POST /api/v1/ai-interviews the only way to write one,
// which is what the client already calls and what the ownership guard already
// covers.
func (s *Server) create(ctx context.Context, svc *service.Service,
ident authctx.Identity, body domain.Record) (domain.Record, error) {
if svc.Resource().Path == service.InterviewsPath {
return s.workflows.CreateInterview(ctx, ident, body)
}
return svc.Create(ctx, ident, body)
}
func (s *Server) handleUpdate(svc *service.Service) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ident, ok := s.authorize(w, r, svc, domain.OpUpdate)
@@ -174,11 +194,6 @@ func (s *Server) handleDelete(svc *service.Service) http.HandlerFunc {
}
}
// decodeBody reads a JSON object body.
//
// DisallowUnknownFields is not used — the target is a map, so every field is
// "known" here. Unknown *columns* are rejected in the service, where the
// resource's schema is available to say which those are.
// decodeInto reads a JSON body into a typed struct.
//
// Beside decodeBody rather than replacing it: the resource handlers genuinely
@@ -200,6 +215,11 @@ func decodeInto(r *http.Request, dst any) error {
return nil
}
// decodeBody reads a JSON object body.
//
// DisallowUnknownFields is not used — the target is a map, so every field is
// "known" here. Unknown *columns* are rejected in the service, where the
// resource's schema is available to say which those are.
func decodeBody(r *http.Request) (domain.Record, error) {
defer func() { _ = r.Body.Close() }()
raw, err := io.ReadAll(http.MaxBytesReader(nil, r.Body, maxBodyBytes))