feat: add case + party CRUD with case events (Phase 1B)
- CaseService: list (paginated, filterable), get detail (with parties, events, deadline count), create, update, soft-delete (archive) - PartyService: list by case, create, update, delete - Auto-create case_events on case creation, status change, party add, and case archive - Auth middleware now resolves tenant_id from user_tenants table - All operations scoped to tenant_id from auth context
This commit is contained in:
@@ -8,14 +8,16 @@ import (
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/google/uuid"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type Middleware struct {
|
||||
jwtSecret []byte
|
||||
db *sqlx.DB
|
||||
}
|
||||
|
||||
func NewMiddleware(jwtSecret string) *Middleware {
|
||||
return &Middleware{jwtSecret: []byte(jwtSecret)}
|
||||
func NewMiddleware(jwtSecret string, db *sqlx.DB) *Middleware {
|
||||
return &Middleware{jwtSecret: []byte(jwtSecret), db: db}
|
||||
}
|
||||
|
||||
func (m *Middleware) RequireAuth(next http.Handler) http.Handler {
|
||||
@@ -33,6 +35,17 @@ func (m *Middleware) RequireAuth(next http.Handler) http.Handler {
|
||||
}
|
||||
|
||||
ctx := ContextWithUserID(r.Context(), userID)
|
||||
|
||||
// Resolve tenant from user_tenants
|
||||
var tenantID uuid.UUID
|
||||
err = m.db.GetContext(r.Context(), &tenantID,
|
||||
"SELECT tenant_id FROM user_tenants WHERE user_id = $1 LIMIT 1", userID)
|
||||
if err != nil {
|
||||
http.Error(w, "no tenant found for user", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
ctx = ContextWithTenantID(ctx, tenantID)
|
||||
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user