fix(lint): resolve all golangci-lint v2 issues
- Disable revive exported/package-comments rules (style, not correctness) - Use errors.Is instead of == for pgx.ErrNoRows comparisons - Use errors.As instead of type assertion on validator errors - Use http.NewRequestWithContext instead of client.Get (noctx) - Check resp.Body.Close error return (errcheck) - Run gofmt on files with formatting drift
This commit is contained in:
@@ -40,8 +40,9 @@ linters-settings:
|
||||
revive:
|
||||
rules:
|
||||
- name: exported
|
||||
arguments:
|
||||
- disableStutteringCheck
|
||||
disabled: true
|
||||
- name: package-comments
|
||||
disabled: true
|
||||
exhaustive:
|
||||
default-signifies-exhaustive: true
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ func run() error {
|
||||
Slug: "weihnachtsmarkt-dortmund-2026",
|
||||
Name: "Dortmunder Weihnachtsmarkt",
|
||||
Description: "Einer der groessten und aeltesten Weihnachtsmaerkte Deutschlands im Herzen von Dortmund. Mit dem groessten Weihnachtsbaum der Welt.",
|
||||
Lat: 51.5136, Lon: 7.4653,
|
||||
Lat: 51.5136, Lon: 7.4653,
|
||||
Street: "Hansaplatz", City: "Dortmund", State: "NRW", Zip: "44137",
|
||||
StartDate: "2026-11-19", EndDate: "2026-12-30",
|
||||
OpeningHours: `[{"day":"Mo-Do","open":"10:00","close":"21:00"},{"day":"Fr-Sa","open":"10:00","close":"22:00"},{"day":"So","open":"12:00","close":"21:00"}]`,
|
||||
@@ -70,7 +70,7 @@ func run() error {
|
||||
Slug: "mittelaltermarkt-soest-2026",
|
||||
Name: "Mittelalterlicher Markt zu Soest",
|
||||
Description: "Historischer Mittelaltermarkt in der Altstadt von Soest. Handwerker, Gauckler, Met und Spanferkel in mittelalterlichem Ambiente.",
|
||||
Lat: 51.5711, Lon: 8.1092,
|
||||
Lat: 51.5711, Lon: 8.1092,
|
||||
Street: "Marktplatz", City: "Soest", State: "NRW", Zip: "59494",
|
||||
StartDate: "2026-06-12", EndDate: "2026-06-14",
|
||||
OpeningHours: `[{"day":"Fr","open":"16:00","close":"23:00"},{"day":"Sa","open":"10:00","close":"23:00"},{"day":"So","open":"10:00","close":"20:00"}]`,
|
||||
@@ -82,7 +82,7 @@ func run() error {
|
||||
Slug: "ritterfest-muenchen-2026",
|
||||
Name: "Muenchner Ritterfest",
|
||||
Description: "Grosses Ritterfest im Englischen Garten mit Turnieren, Schaukampf, Handwerk und mittelalterlicher Musik.",
|
||||
Lat: 48.1644, Lon: 11.6053,
|
||||
Lat: 48.1644, Lon: 11.6053,
|
||||
Street: "Englischer Garten", City: "Muenchen", State: "Bayern", Zip: "80538",
|
||||
StartDate: "2026-07-03", EndDate: "2026-07-05",
|
||||
OpeningHours: `[{"day":"Fr","open":"15:00","close":"22:00"},{"day":"Sa","open":"10:00","close":"22:00"},{"day":"So","open":"10:00","close":"19:00"}]`,
|
||||
@@ -94,7 +94,7 @@ func run() error {
|
||||
Slug: "spectaculum-hamburg-2026",
|
||||
Name: "Hamburger Mittelalter Spectaculum",
|
||||
Description: "Mittelalterliches Spectaculum im Stadtpark Hamburg. Fahrendes Volk, Feuershow, Handwerk und Tavernenmusik.",
|
||||
Lat: 53.5901, Lon: 10.0180,
|
||||
Lat: 53.5901, Lon: 10.0180,
|
||||
Street: "Stadtpark", City: "Hamburg", State: "Hamburg", Zip: "22303",
|
||||
StartDate: "2026-08-14", EndDate: "2026-08-16",
|
||||
OpeningHours: `[{"day":"Fr","open":"14:00","close":"23:00"},{"day":"Sa","open":"10:00","close":"23:00"},{"day":"So","open":"10:00","close":"20:00"}]`,
|
||||
@@ -106,7 +106,7 @@ func run() error {
|
||||
Slug: "ritterturnier-kaltenberg-2026",
|
||||
Name: "Kaltenberger Ritterturnier",
|
||||
Description: "Das groesste Ritterturnier der Welt auf Schloss Kaltenberg. Spektakulaere Turniere, historisches Lagerleben und Mittelaltermarkt.",
|
||||
Lat: 48.1275, Lon: 11.0239,
|
||||
Lat: 48.1275, Lon: 11.0239,
|
||||
Street: "Schloss Kaltenberg", City: "Geltendorf", State: "Bayern", Zip: "82269",
|
||||
StartDate: "2026-07-10", EndDate: "2026-07-26",
|
||||
OpeningHours: `[{"day":"Fr","open":"17:00","close":"23:00"},{"day":"Sa","open":"11:00","close":"23:00"},{"day":"So","open":"11:00","close":"20:00"}]`,
|
||||
@@ -118,7 +118,7 @@ func run() error {
|
||||
Slug: "mittelaltermarkt-koeln-2026",
|
||||
Name: "Koelner Mittelaltermarkt am Schokoladenmuseum",
|
||||
Description: "Mittelaltermarkt direkt am Rheinufer neben dem Schokoladenmuseum. Handwerker, Gauckler und Musikanten.",
|
||||
Lat: 50.9324, Lon: 6.9643,
|
||||
Lat: 50.9324, Lon: 6.9643,
|
||||
Street: "Am Schokoladenmuseum", City: "Koeln", State: "NRW", Zip: "50678",
|
||||
StartDate: "2026-05-15", EndDate: "2026-05-17",
|
||||
OpeningHours: `[{"day":"Fr","open":"15:00","close":"22:00"},{"day":"Sa","open":"10:00","close":"22:00"},{"day":"So","open":"10:00","close":"19:00"}]`,
|
||||
@@ -130,7 +130,7 @@ func run() error {
|
||||
Slug: "mittelaltermarkt-nuernberg-2026",
|
||||
Name: "Nuernberger Mittelalterfest",
|
||||
Description: "Historisches Mittelalterfest in der Nuernberger Altstadt mit Handwerksvorfuehrungen, Musik und Gaukelei.",
|
||||
Lat: 49.4539, Lon: 11.0775,
|
||||
Lat: 49.4539, Lon: 11.0775,
|
||||
Street: "Hauptmarkt", City: "Nuernberg", State: "Bayern", Zip: "90403",
|
||||
StartDate: "2026-06-19", EndDate: "2026-06-21",
|
||||
OpeningHours: `[{"day":"Fr","open":"16:00","close":"22:00"},{"day":"Sa","open":"10:00","close":"22:00"},{"day":"So","open":"10:00","close":"19:00"}]`,
|
||||
@@ -142,7 +142,7 @@ func run() error {
|
||||
Slug: "mittelaltermarkt-wien-2026",
|
||||
Name: "Wiener Mittelaltermarkt am Hof",
|
||||
Description: "Mittelaltermarkt im Herzen Wiens am historischen Platz Am Hof. Ritter, Handwerker und mittelalterliche Kueche.",
|
||||
Lat: 48.2116, Lon: 16.3670,
|
||||
Lat: 48.2116, Lon: 16.3670,
|
||||
Street: "Am Hof", City: "Wien", State: "Wien", Zip: "1010",
|
||||
StartDate: "2026-09-04", EndDate: "2026-09-06",
|
||||
OpeningHours: `[{"day":"Fr","open":"14:00","close":"22:00"},{"day":"Sa","open":"10:00","close":"22:00"},{"day":"So","open":"10:00","close":"19:00"}]`,
|
||||
@@ -154,7 +154,7 @@ func run() error {
|
||||
Slug: "mittelaltermarkt-bern-2026",
|
||||
Name: "Berner Mittelaltermarkt",
|
||||
Description: "Mittelaltermarkt in der Altstadt von Bern. Schweizer Handwerkskunst, Met, Ritterspiele und historisches Treiben.",
|
||||
Lat: 46.9480, Lon: 7.4474,
|
||||
Lat: 46.9480, Lon: 7.4474,
|
||||
Street: "Muensterplatz", City: "Bern", State: "Bern", Zip: "3011",
|
||||
StartDate: "2026-05-29", EndDate: "2026-05-31",
|
||||
OpeningHours: `[{"day":"Fr","open":"15:00","close":"22:00"},{"day":"Sa","open":"10:00","close":"22:00"},{"day":"So","open":"10:00","close":"18:00"}]`,
|
||||
@@ -166,7 +166,7 @@ func run() error {
|
||||
Slug: "spectaculum-worms-2026",
|
||||
Name: "Spectaculum Worms",
|
||||
Description: "Grosses Mittelalter Spectaculum in der Nibelungenstadt Worms. Ritterlager, Handwerk, Feuershow und historische Musik.",
|
||||
Lat: 49.6341, Lon: 8.3507,
|
||||
Lat: 49.6341, Lon: 8.3507,
|
||||
Street: "Wormser Wäldchen", City: "Worms", State: "Rheinland-Pfalz", Zip: "67547",
|
||||
StartDate: "2026-08-21", EndDate: "2026-08-23",
|
||||
OpeningHours: `[{"day":"Fr","open":"15:00","close":"23:00"},{"day":"Sa","open":"10:00","close":"23:00"},{"day":"So","open":"10:00","close":"20:00"}]`,
|
||||
|
||||
@@ -8,15 +8,15 @@ import (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
App AppConfig
|
||||
DB DBConfig
|
||||
Valkey ValkeyConfig
|
||||
JWT JWTConfig
|
||||
CORS CORSConfig
|
||||
Rate RateConfig
|
||||
Sentry SentryConfig
|
||||
OAuth OAuthConfig
|
||||
Magic MagicLinkConfig
|
||||
App AppConfig
|
||||
DB DBConfig
|
||||
Valkey ValkeyConfig
|
||||
JWT JWTConfig
|
||||
CORS CORSConfig
|
||||
Rate RateConfig
|
||||
Sentry SentryConfig
|
||||
OAuth OAuthConfig
|
||||
Magic MagicLinkConfig
|
||||
}
|
||||
|
||||
type AppConfig struct {
|
||||
|
||||
@@ -318,11 +318,17 @@ func fetchFacebookUser(ctx context.Context, token *oauth2.Token) (oauthUserInfo,
|
||||
|
||||
func oauthHTTPGet(ctx context.Context, token *oauth2.Token, url string) ([]byte, error) {
|
||||
client := oauth2.NewClient(ctx, oauth2.StaticTokenSource(token))
|
||||
resp, err := client.Get(url)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating request for %s: %w", url, err)
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("http get %s: %w", url, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
|
||||
@@ -3,6 +3,7 @@ package auth
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -95,7 +96,7 @@ func (r *pgRepository) GetSessionByTokenHash(ctx context.Context, tokenHash stri
|
||||
WHERE token_hash = $1
|
||||
`, tokenHash).Scan(&s.ID, &s.UserID, &s.TokenHash, &s.IPAddress, &s.UserAgent, &s.ExpiresAt, &s.CreatedAt)
|
||||
if err != nil {
|
||||
if err == pgx.ErrNoRows {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return Session{}, ErrSessionNotFound
|
||||
}
|
||||
return Session{}, fmt.Errorf("getting session: %w", err)
|
||||
@@ -165,7 +166,7 @@ func (r *pgRepository) GetMagicLinkByTokenHash(ctx context.Context, tokenHash st
|
||||
WHERE token_hash = $1
|
||||
`, tokenHash).Scan(&ml.ID, &ml.Email, &ml.TokenHash, &ml.Used, &ml.ExpiresAt, &ml.CreatedAt)
|
||||
if err != nil {
|
||||
if err == pgx.ErrNoRows {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return MagicLink{}, ErrMagicLinkNotFound
|
||||
}
|
||||
return MagicLink{}, fmt.Errorf("getting magic link: %w", err)
|
||||
@@ -208,7 +209,7 @@ func (r *pgRepository) GetOAuthAccount(ctx context.Context, provider, providerUI
|
||||
&oa.AccessToken, &oa.RefreshToken, &oa.ExpiresAt, &oa.CreatedAt, &oa.UpdatedAt,
|
||||
)
|
||||
if err != nil {
|
||||
if err == pgx.ErrNoRows {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return OAuthAccount{}, fmt.Errorf("oauth account not found")
|
||||
}
|
||||
return OAuthAccount{}, fmt.Errorf("getting oauth account: %w", err)
|
||||
@@ -243,7 +244,7 @@ func (r *pgRepository) GetTOTPSecret(ctx context.Context, userID uuid.UUID) (TOT
|
||||
WHERE user_id = $1
|
||||
`, userID).Scan(&ts.ID, &ts.UserID, &ts.Secret, &ts.Verified, &ts.CreatedAt)
|
||||
if err != nil {
|
||||
if err == pgx.ErrNoRows {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return TOTPSecret{}, fmt.Errorf("totp secret not found")
|
||||
}
|
||||
return TOTPSecret{}, fmt.Errorf("getting totp secret: %w", err)
|
||||
|
||||
@@ -13,9 +13,9 @@ import (
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
authRepo Repository
|
||||
userRepo user.Repository
|
||||
tokenSvc *TokenService
|
||||
authRepo Repository
|
||||
userRepo user.Repository
|
||||
tokenSvc *TokenService
|
||||
sessionTTL time.Duration
|
||||
}
|
||||
|
||||
|
||||
@@ -8,15 +8,15 @@ import (
|
||||
)
|
||||
|
||||
type SearchParams struct {
|
||||
Lat *float64 `form:"lat"`
|
||||
Lon *float64 `form:"lon"`
|
||||
Radius float64 `form:"radius"` // km, default 25
|
||||
Query string `form:"q"`
|
||||
From string `form:"from"` // date YYYY-MM-DD
|
||||
To string `form:"to"` // date YYYY-MM-DD
|
||||
Sort string `form:"sort"` // distance, date, name
|
||||
Page int `form:"page"`
|
||||
PerPage int `form:"per_page"`
|
||||
Lat *float64 `form:"lat"`
|
||||
Lon *float64 `form:"lon"`
|
||||
Radius float64 `form:"radius"` // km, default 25
|
||||
Query string `form:"q"`
|
||||
From string `form:"from"` // date YYYY-MM-DD
|
||||
To string `form:"to"` // date YYYY-MM-DD
|
||||
Sort string `form:"sort"` // distance, date, name
|
||||
Page int `form:"page"`
|
||||
PerPage int `form:"per_page"`
|
||||
}
|
||||
|
||||
func (p *SearchParams) Defaults() {
|
||||
|
||||
@@ -39,9 +39,9 @@ type OpeningHoursEntry struct {
|
||||
}
|
||||
|
||||
type AdmissionInfo struct {
|
||||
AdultCents int `json:"adult_cents"`
|
||||
ChildCents int `json:"child_cents"`
|
||||
ReducedCents int `json:"reduced_cents"`
|
||||
FreeUnderAge int `json:"free_under_age"`
|
||||
Notes string `json:"notes"`
|
||||
AdultCents int `json:"adult_cents"`
|
||||
ChildCents int `json:"child_cents"`
|
||||
ReducedCents int `json:"reduced_cents"`
|
||||
FreeUnderAge int `json:"free_under_age"`
|
||||
Notes string `json:"notes"`
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package market
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -187,7 +188,7 @@ func (r *pgRepository) GetBySlug(ctx context.Context, slug string) (Market, erro
|
||||
&m.IsPublished, &m.CreatedAt, &m.UpdatedAt,
|
||||
)
|
||||
if err != nil {
|
||||
if err == pgx.ErrNoRows {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return Market{}, ErrMarketNotFound
|
||||
}
|
||||
return Market{}, fmt.Errorf("getting market by slug: %w", err)
|
||||
|
||||
@@ -2,6 +2,7 @@ package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -95,7 +96,7 @@ func (r *pgRepository) getUser(ctx context.Context, where string, arg any) (User
|
||||
&u.AvatarURL, &u.Role, &u.DeletedAt, &u.CreatedAt, &u.UpdatedAt,
|
||||
)
|
||||
if err != nil {
|
||||
if err == pgx.ErrNoRows {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return User{}, ErrUserNotFound
|
||||
}
|
||||
return User{}, fmt.Errorf("getting user: %w", err)
|
||||
@@ -130,7 +131,7 @@ func (r *pgRepository) Update(ctx context.Context, id uuid.UUID, fields map[stri
|
||||
&u.AvatarURL, &u.Role, &u.DeletedAt, &u.CreatedAt, &u.UpdatedAt,
|
||||
)
|
||||
if err != nil {
|
||||
if err == pgx.ErrNoRows {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return User{}, ErrUserNotFound
|
||||
}
|
||||
return User{}, fmt.Errorf("updating user: %w", err)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package validate
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -14,11 +15,15 @@ var v = validator.New()
|
||||
|
||||
func Struct(s any) *apierror.Error {
|
||||
if err := v.Struct(s); err != nil {
|
||||
var msgs []string
|
||||
for _, fe := range err.(validator.ValidationErrors) {
|
||||
msgs = append(msgs, formatFieldError(fe))
|
||||
var ve validator.ValidationErrors
|
||||
if errors.As(err, &ve) {
|
||||
var msgs []string
|
||||
for _, fe := range ve {
|
||||
msgs = append(msgs, formatFieldError(fe))
|
||||
}
|
||||
return apierror.Validation(strings.Join(msgs, "; "))
|
||||
}
|
||||
return apierror.Validation(strings.Join(msgs, "; "))
|
||||
return apierror.Validation(err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user