this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: remove openapi part, update instructions

+14 -417
+3 -2
Justfile
··· 15 15 updateschema: 16 16 curl -fsSL https://git.inpt.fr/churros/churros/-/raw/main/packages/db/prisma/schema.prisma -o schema.prisma 17 17 18 - updateopenapi: 19 - go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=openapi-config.yaml openapi.yaml 18 + genprisma: 19 + go get github.com/steebchen/prisma-client-go 20 + go run github.com/steebchen/prisma-client-go generate 20 21 21 22 generate: 22 23 just updateschema
+9
README.md
··· 1 1 # churros/notella 2 2 3 3 Notification queue server for [Churros](https://git.inpt.fr/churros/churros) 4 + 5 + ## Installation 6 + 7 + ```bash 8 + # generate prisma client 9 + just genprisma 10 + # start 11 + just 12 + ```
-1
go.mod
··· 5 5 require ( 6 6 github.com/caarlos0/env/v11 v11.2.2 7 7 github.com/ewen-lbh/label-logger-go v0.1.1 8 - github.com/google/uuid v1.6.0 9 8 github.com/joho/godotenv v1.5.1 10 9 github.com/orcaman/concurrent-map/v2 v2.0.1 11 10 github.com/shopspring/decimal v1.4.0
-6
go.sum
··· 6 6 github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w= 7 7 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 8 8 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 9 - github.com/ewen-lbh/label-logger-go v0.0.0-20241011201023-2c63f6a50d58 h1:oS+iVtATEd6oi6vA0Zn8tWhL7K1KEyE5jS2u6K3I0cU= 10 - github.com/ewen-lbh/label-logger-go v0.0.0-20241011201023-2c63f6a50d58/go.mod h1:ORVakjovWm+MfrGXmHBZAJvxNqYwAxdG3Sev8CXXChM= 11 9 github.com/ewen-lbh/label-logger-go v0.1.1 h1:jHTjmhD1OBP7xqdG+xs6NvO96JJ3+5mhskTKVJxLDm4= 12 10 github.com/ewen-lbh/label-logger-go v0.1.1/go.mod h1:ORVakjovWm+MfrGXmHBZAJvxNqYwAxdG3Sev8CXXChM= 13 11 github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= 14 12 github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= 15 - github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 16 - github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 17 13 github.com/gosuri/uilive v0.0.4 h1:hUEBpQDj8D8jXgtCdBu7sWsy5sbW/5GhuO8KBwJ2jyY= 18 14 github.com/gosuri/uilive v0.0.4/go.mod h1:V/epo5LjjlDE5RJUcqx8dbw+zc93y5Ya3yg8tfZ74VI= 19 15 github.com/gosuri/uiprogress v0.0.1 h1:0kpv/XY/qTmFWl/SkaJykZXrBBzwwadmW8fRb7RJSxw= ··· 57 53 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 58 54 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 59 55 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 60 - golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= 61 - golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 62 56 golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= 63 57 golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 64 58 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-6
openapi-config.yaml
··· 1 - # yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/main/configuration-schema.json 2 - package: openapi 3 - generate: 4 - std-http-server: true 5 - models: true 6 - output: openapi/openapi.go
-53
openapi.yaml
··· 1 - openapi: "3.1.1" 2 - info: 3 - version: 1.0.0 4 - title: churros/notella 5 - paths: 6 - /schedule: 7 - post: 8 - requestBody: 9 - required: true 10 - content: 11 - application/json: 12 - schema: 13 - $ref: "#/components/schemas/ScheduleRequest" 14 - responses: 15 - "201": 16 - description: created 17 - /schedule/batch: 18 - post: 19 - requestBody: 20 - required: true 21 - content: 22 - application/json: 23 - schema: 24 - type: array 25 - items: 26 - $ref: "#/components/schemas/ScheduleRequest" 27 - responses: 28 - "201": 29 - description: created 30 - components: 31 - schemas: 32 - ScheduleRequest: 33 - type: object 34 - required: 35 - - when 36 - - resource 37 - - event 38 - properties: 39 - when: 40 - type: string 41 - format: date-time 42 - resource: 43 - type: string 44 - x-go-type: notella.ChurrosId 45 - x-go-type-import: 46 - path: git.inpt.fr/churros/notella 47 - name: notella 48 - event: 49 - type: string 50 - x-go-type: notella.Event 51 - x-go-type-import: 52 - path: git.inpt.fr/churros/notella 53 - name: notella
-203
openapi/openapi.go
··· 1 - //go:build go1.22 2 - 3 - // Package openapi provides primitives to interact with the openapi HTTP API. 4 - // 5 - // Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.4.1 DO NOT EDIT. 6 - package openapi 7 - 8 - import ( 9 - "fmt" 10 - "net/http" 11 - "time" 12 - 13 - notella "git.inpt.fr/churros/notella" 14 - ) 15 - 16 - // ScheduleRequest defines model for ScheduleRequest. 17 - type ScheduleRequest struct { 18 - Event notella.Event `json:"event"` 19 - Resource notella.ChurrosId `json:"resource"` 20 - When time.Time `json:"when"` 21 - } 22 - 23 - // PostScheduleBatchJSONBody defines parameters for PostScheduleBatch. 24 - type PostScheduleBatchJSONBody = []ScheduleRequest 25 - 26 - // PostScheduleJSONRequestBody defines body for PostSchedule for application/json ContentType. 27 - type PostScheduleJSONRequestBody = ScheduleRequest 28 - 29 - // PostScheduleBatchJSONRequestBody defines body for PostScheduleBatch for application/json ContentType. 30 - type PostScheduleBatchJSONRequestBody = PostScheduleBatchJSONBody 31 - 32 - // ServerInterface represents all server handlers. 33 - type ServerInterface interface { 34 - 35 - // (POST /schedule) 36 - PostSchedule(w http.ResponseWriter, r *http.Request) 37 - 38 - // (POST /schedule/batch) 39 - PostScheduleBatch(w http.ResponseWriter, r *http.Request) 40 - } 41 - 42 - // ServerInterfaceWrapper converts contexts to parameters. 43 - type ServerInterfaceWrapper struct { 44 - Handler ServerInterface 45 - HandlerMiddlewares []MiddlewareFunc 46 - ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) 47 - } 48 - 49 - type MiddlewareFunc func(http.Handler) http.Handler 50 - 51 - // PostSchedule operation middleware 52 - func (siw *ServerInterfaceWrapper) PostSchedule(w http.ResponseWriter, r *http.Request) { 53 - 54 - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 55 - siw.Handler.PostSchedule(w, r) 56 - })) 57 - 58 - for _, middleware := range siw.HandlerMiddlewares { 59 - handler = middleware(handler) 60 - } 61 - 62 - handler.ServeHTTP(w, r) 63 - } 64 - 65 - // PostScheduleBatch operation middleware 66 - func (siw *ServerInterfaceWrapper) PostScheduleBatch(w http.ResponseWriter, r *http.Request) { 67 - 68 - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 69 - siw.Handler.PostScheduleBatch(w, r) 70 - })) 71 - 72 - for _, middleware := range siw.HandlerMiddlewares { 73 - handler = middleware(handler) 74 - } 75 - 76 - handler.ServeHTTP(w, r) 77 - } 78 - 79 - type UnescapedCookieParamError struct { 80 - ParamName string 81 - Err error 82 - } 83 - 84 - func (e *UnescapedCookieParamError) Error() string { 85 - return fmt.Sprintf("error unescaping cookie parameter '%s'", e.ParamName) 86 - } 87 - 88 - func (e *UnescapedCookieParamError) Unwrap() error { 89 - return e.Err 90 - } 91 - 92 - type UnmarshalingParamError struct { 93 - ParamName string 94 - Err error 95 - } 96 - 97 - func (e *UnmarshalingParamError) Error() string { 98 - return fmt.Sprintf("Error unmarshaling parameter %s as JSON: %s", e.ParamName, e.Err.Error()) 99 - } 100 - 101 - func (e *UnmarshalingParamError) Unwrap() error { 102 - return e.Err 103 - } 104 - 105 - type RequiredParamError struct { 106 - ParamName string 107 - } 108 - 109 - func (e *RequiredParamError) Error() string { 110 - return fmt.Sprintf("Query argument %s is required, but not found", e.ParamName) 111 - } 112 - 113 - type RequiredHeaderError struct { 114 - ParamName string 115 - Err error 116 - } 117 - 118 - func (e *RequiredHeaderError) Error() string { 119 - return fmt.Sprintf("Header parameter %s is required, but not found", e.ParamName) 120 - } 121 - 122 - func (e *RequiredHeaderError) Unwrap() error { 123 - return e.Err 124 - } 125 - 126 - type InvalidParamFormatError struct { 127 - ParamName string 128 - Err error 129 - } 130 - 131 - func (e *InvalidParamFormatError) Error() string { 132 - return fmt.Sprintf("Invalid format for parameter %s: %s", e.ParamName, e.Err.Error()) 133 - } 134 - 135 - func (e *InvalidParamFormatError) Unwrap() error { 136 - return e.Err 137 - } 138 - 139 - type TooManyValuesForParamError struct { 140 - ParamName string 141 - Count int 142 - } 143 - 144 - func (e *TooManyValuesForParamError) Error() string { 145 - return fmt.Sprintf("Expected one value for %s, got %d", e.ParamName, e.Count) 146 - } 147 - 148 - // Handler creates http.Handler with routing matching OpenAPI spec. 149 - func Handler(si ServerInterface) http.Handler { 150 - return HandlerWithOptions(si, StdHTTPServerOptions{}) 151 - } 152 - 153 - // ServeMux is an abstraction of http.ServeMux. 154 - type ServeMux interface { 155 - HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) 156 - ServeHTTP(w http.ResponseWriter, r *http.Request) 157 - } 158 - 159 - type StdHTTPServerOptions struct { 160 - BaseURL string 161 - BaseRouter ServeMux 162 - Middlewares []MiddlewareFunc 163 - ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) 164 - } 165 - 166 - // HandlerFromMux creates http.Handler with routing matching OpenAPI spec based on the provided mux. 167 - func HandlerFromMux(si ServerInterface, m ServeMux) http.Handler { 168 - return HandlerWithOptions(si, StdHTTPServerOptions{ 169 - BaseRouter: m, 170 - }) 171 - } 172 - 173 - func HandlerFromMuxWithBaseURL(si ServerInterface, m ServeMux, baseURL string) http.Handler { 174 - return HandlerWithOptions(si, StdHTTPServerOptions{ 175 - BaseURL: baseURL, 176 - BaseRouter: m, 177 - }) 178 - } 179 - 180 - // HandlerWithOptions creates http.Handler with additional options 181 - func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.Handler { 182 - m := options.BaseRouter 183 - 184 - if m == nil { 185 - m = http.NewServeMux() 186 - } 187 - if options.ErrorHandlerFunc == nil { 188 - options.ErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { 189 - http.Error(w, err.Error(), http.StatusBadRequest) 190 - } 191 - } 192 - 193 - wrapper := ServerInterfaceWrapper{ 194 - Handler: si, 195 - HandlerMiddlewares: options.Middlewares, 196 - ErrorHandlerFunc: options.ErrorHandlerFunc, 197 - } 198 - 199 - m.HandleFunc("POST "+options.BaseURL+"/schedule", wrapper.PostSchedule) 200 - m.HandleFunc("POST "+options.BaseURL+"/schedule/batch", wrapper.PostScheduleBatch) 201 - 202 - return m 203 - }
+2 -63
package-lock.json
··· 1 1 { 2 - "name": "notella", 2 + "name": "churros-notella", 3 3 "lockfileVersion": 3, 4 4 "requires": true, 5 5 "packages": { ··· 8 8 "@prisma/client": "^5.20.0" 9 9 }, 10 10 "devDependencies": { 11 - "@pothos/core": "^4.3.0", 12 - "@pothos/plugin-prisma": "^4.2.1", 13 11 "prisma": "^5.20.0" 14 - } 15 - }, 16 - "node_modules/@pothos/core": { 17 - "version": "4.3.0", 18 - "resolved": "https://registry.npmjs.org/@pothos/core/-/core-4.3.0.tgz", 19 - "integrity": "sha512-i4nyI8wSCjxdHUomqQ2K3FH0Glklomfv4tJNifQVU9lPtQKoKaS69VxGv+fru0HAZzb1eC1XPEPN3XPCYcvZ7Q==", 20 - "dev": true, 21 - "peerDependencies": { 22 - "graphql": ">=16.6.0" 23 - } 24 - }, 25 - "node_modules/@pothos/plugin-prisma": { 26 - "version": "4.2.1", 27 - "resolved": "https://registry.npmjs.org/@pothos/plugin-prisma/-/plugin-prisma-4.2.1.tgz", 28 - "integrity": "sha512-leFWc+akd/EbrsAGEL3Th0fOEl3MnNTGimoLpLa+89rNppiymJz6QmpSq88jTa6yFwPiKU0EsICJ6xv0ioCzig==", 29 - "dev": true, 30 - "dependencies": { 31 - "@prisma/generator-helper": "^5.17.0" 32 - }, 33 - "bin": { 34 - "prisma-pothos-types": "bin/generator.js" 35 - }, 36 - "peerDependencies": { 37 - "@pothos/core": "*", 38 - "@prisma/client": "*", 39 - "graphql": ">=16.6.0", 40 - "typescript": ">=4.7.2" 41 12 } 42 13 }, 43 14 "node_modules/@prisma/client": { ··· 93 64 "@prisma/get-platform": "5.20.0" 94 65 } 95 66 }, 96 - "node_modules/@prisma/generator-helper": { 97 - "version": "5.20.0", 98 - "resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-5.20.0.tgz", 99 - "integrity": "sha512-37Aibw0wVRQgQVtCdNAIN71YFnSQfvetok7vd95KKkYkQRbEx94gsvPDpyN9Mw7p3IwA3nFgPfLc3jBRztUkKw==", 100 - "dev": true, 101 - "dependencies": { 102 - "@prisma/debug": "5.20.0" 103 - } 104 - }, 105 67 "node_modules/@prisma/get-platform": { 106 68 "version": "5.20.0", 107 69 "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.20.0.tgz", ··· 115 77 "version": "2.3.3", 116 78 "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 117 79 "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 80 + "dev": true, 118 81 "hasInstallScript": true, 119 82 "optional": true, 120 83 "os": [ ··· 124 87 "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 125 88 } 126 89 }, 127 - "node_modules/graphql": { 128 - "version": "16.9.0", 129 - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.9.0.tgz", 130 - "integrity": "sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==", 131 - "dev": true, 132 - "peer": true, 133 - "engines": { 134 - "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" 135 - } 136 - }, 137 90 "node_modules/prisma": { 138 91 "version": "5.20.0", 139 92 "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.20.0.tgz", ··· 151 104 }, 152 105 "optionalDependencies": { 153 106 "fsevents": "2.3.3" 154 - } 155 - }, 156 - "node_modules/typescript": { 157 - "version": "5.6.3", 158 - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", 159 - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", 160 - "dev": true, 161 - "peer": true, 162 - "bin": { 163 - "tsc": "bin/tsc", 164 - "tsserver": "bin/tsserver" 165 - }, 166 - "engines": { 167 - "node": ">=14.17" 168 107 } 169 108 } 170 109 }
-8
server/main.go
··· 8 8 "os" 9 9 10 10 "git.inpt.fr/churros/notella" 11 - "git.inpt.fr/churros/notella/openapi" 12 11 "github.com/caarlos0/env/v11" 13 12 "github.com/common-nighthawk/go-figure" 14 13 ll "github.com/ewen-lbh/label-logger-go" ··· 55 54 ll.Info("starting scheduler") 56 55 go notella.StartScheduler() 57 56 58 - ll.Info("starting server on port %d", config.Port) 59 - mux := http.NewServeMux() 60 - server := &http.Server{ 61 - Addr: fmt.Sprintf(":%d", config.Port), 62 - Handler: openapi.HandlerFromMux(NewServer(), mux), 63 - } 64 - server.ListenAndServe() 65 57 }
-56
server/server.go
··· 1 - package main 2 - 3 - import ( 4 - "net/http" 5 - "sync" 6 - 7 - "git.inpt.fr/churros/notella" 8 - "git.inpt.fr/churros/notella/openapi" 9 - "github.com/google/uuid" 10 - ) 11 - 12 - type Server struct{} 13 - 14 - func NewServer() Server { 15 - return Server{} 16 - } 17 - 18 - func (Server) PostSchedule(w http.ResponseWriter, r *http.Request) { 19 - var req openapi.PostScheduleJSONRequestBody 20 - decodeRequest(w, r, &req) 21 - 22 - job := notella.ScheduledJob{ 23 - ID: uuid.New().String(), 24 - When: req.When, 25 - Object: req.Resource, 26 - Event: req.Event, 27 - } 28 - 29 - job.Schedule() 30 - w.WriteHeader(http.StatusCreated) 31 - } 32 - 33 - func (Server) PostScheduleBatch(w http.ResponseWriter, r *http.Request) { 34 - var req openapi.PostScheduleBatchJSONRequestBody 35 - decodeRequest(w, r, &req) 36 - 37 - var wg sync.WaitGroup 38 - 39 - for _, schedule := range req { 40 - wg.Add(1) 41 - job := notella.ScheduledJob{ 42 - ID: uuid.New().String(), 43 - When: schedule.When, 44 - Object: schedule.Resource, 45 - Event: schedule.Event, 46 - } 47 - 48 - go func(job notella.ScheduledJob, wg *sync.WaitGroup) { 49 - job.Schedule() 50 - wg.Done() 51 - }(job, &wg) 52 - } 53 - 54 - wg.Wait() 55 - w.WriteHeader(http.StatusCreated) 56 - }
-19
server/utils.go
··· 1 1 package main 2 2 3 3 import ( 4 - "encoding/json" 5 - "io" 6 - "net/http" 7 4 "net/url" 8 - 9 - ll "github.com/ewen-lbh/label-logger-go" 10 5 ) 11 6 12 7 func redactURL(rawURL string) string { ··· 22 17 u.User = url.UserPassword(u.User.Username(), "REDACTED") 23 18 return u.String() 24 19 } 25 - 26 - func decodeRequest(w http.ResponseWriter, r *http.Request, v any) { 27 - body, err := io.ReadAll(r.Body) 28 - if err != nil { 29 - ll.ErrorDisplay("could not read request body: %w", err) 30 - http.Error(w, "could not read request body", http.StatusBadRequest) 31 - } 32 - 33 - err = json.Unmarshal(body, &v) 34 - if err != nil { 35 - ll.ErrorDisplay("could not decode json", err) 36 - http.Error(w, "could not decode json", http.StatusBadRequest) 37 - } 38 - }