Compare commits
No commits in common. "production" and "main" have entirely different histories.
production
...
main
|
|
@ -1,67 +0,0 @@
|
||||||
-- Seed TRUE_FALSE and SHORT_ANSWER question types
|
|
||||||
-- Ensures question sets contain non-MCQ questions for end-to-end testing.
|
|
||||||
|
|
||||||
-- ======================================================
|
|
||||||
-- TRUE_FALSE questions (stored in questions + question_options)
|
|
||||||
-- ======================================================
|
|
||||||
INSERT INTO questions (
|
|
||||||
id,
|
|
||||||
question_text,
|
|
||||||
question_type,
|
|
||||||
difficulty_level,
|
|
||||||
points,
|
|
||||||
status,
|
|
||||||
created_at
|
|
||||||
)
|
|
||||||
VALUES
|
|
||||||
(27, 'The Python interpreter executes Python code top-to-bottom.', 'TRUE_FALSE', 'EASY', 1, 'PUBLISHED', CURRENT_TIMESTAMP)
|
|
||||||
ON CONFLICT (id) DO NOTHING;
|
|
||||||
|
|
||||||
-- question_options for TRUE_FALSE: use two options with exactly one correct
|
|
||||||
INSERT INTO question_options (question_id, option_text, option_order, is_correct)
|
|
||||||
VALUES
|
|
||||||
(27, 'True', 1, TRUE),
|
|
||||||
(27, 'False', 2, FALSE)
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
|
|
||||||
-- ======================================================
|
|
||||||
-- SHORT_ANSWER questions (stored in questions + question_short_answers)
|
|
||||||
-- ======================================================
|
|
||||||
INSERT INTO questions (
|
|
||||||
id,
|
|
||||||
question_text,
|
|
||||||
question_type,
|
|
||||||
difficulty_level,
|
|
||||||
points,
|
|
||||||
status,
|
|
||||||
created_at
|
|
||||||
)
|
|
||||||
VALUES
|
|
||||||
(29, 'What keyword is used in Python to define a function?', 'SHORT_ANSWER', 'EASY', 1, 'PUBLISHED', CURRENT_TIMESTAMP)
|
|
||||||
ON CONFLICT (id) DO NOTHING;
|
|
||||||
|
|
||||||
INSERT INTO question_short_answers (question_id, acceptable_answer, match_type)
|
|
||||||
VALUES
|
|
||||||
(29, 'def', 'EXACT')
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
|
|
||||||
-- ======================================================
|
|
||||||
-- Link new questions into existing question sets
|
|
||||||
-- Question Set 1: Initial Assessment (set_id = 1, PUBLISHED)
|
|
||||||
-- Question Set 2: Python Basics Assessment (set_id = 2, PUBLISHED)
|
|
||||||
-- ======================================================
|
|
||||||
INSERT INTO question_set_items (set_id, question_id, display_order)
|
|
||||||
VALUES
|
|
||||||
(1, 27, 17),
|
|
||||||
(1, 29, 18),
|
|
||||||
(2, 27, 3),
|
|
||||||
(2, 29, 4)
|
|
||||||
ON CONFLICT (set_id, question_id) DO NOTHING;
|
|
||||||
|
|
||||||
-- ======================================================
|
|
||||||
-- Reset sequences to avoid ID collisions after seeding
|
|
||||||
-- ======================================================
|
|
||||||
SELECT setval(pg_get_serial_sequence('questions', 'id'), COALESCE((SELECT MAX(id) FROM questions), 1), true);
|
|
||||||
SELECT setval(pg_get_serial_sequence('question_options', 'id'), COALESCE((SELECT MAX(id) FROM question_options), 1), true);
|
|
||||||
SELECT setval(pg_get_serial_sequence('question_short_answers', 'id'), COALESCE((SELECT MAX(id) FROM question_short_answers), 1), true);
|
|
||||||
|
|
||||||
|
|
@ -19,9 +19,6 @@ type RBACStore interface {
|
||||||
GetPermissionByKey(ctx context.Context, key string) (domain.Permission, error)
|
GetPermissionByKey(ctx context.Context, key string) (domain.Permission, error)
|
||||||
|
|
||||||
SetRolePermissions(ctx context.Context, roleID int64, permissionIDs []int64) error
|
SetRolePermissions(ctx context.Context, roleID int64, permissionIDs []int64) error
|
||||||
// AddRolePermissions inserts permissions into role without removing existing ones.
|
|
||||||
// It is safe to call repeatedly (idempotent) as it relies on ON CONFLICT DO NOTHING.
|
|
||||||
AddRolePermissions(ctx context.Context, roleID int64, permissionIDs []int64) error
|
|
||||||
GetRolePermissions(ctx context.Context, roleID int64) ([]domain.Permission, error)
|
GetRolePermissions(ctx context.Context, roleID int64) ([]domain.Permission, error)
|
||||||
|
|
||||||
GetAllRolesWithPermissions(ctx context.Context) (map[string]map[string]struct{}, error)
|
GetAllRolesWithPermissions(ctx context.Context) (map[string]map[string]struct{}, error)
|
||||||
|
|
|
||||||
|
|
@ -150,17 +150,6 @@ func (s *Store) SetRolePermissions(ctx context.Context, roleID int64, permission
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) AddRolePermissions(ctx context.Context, roleID int64, permissionIDs []int64) error {
|
|
||||||
if len(permissionIDs) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// Uses ON CONFLICT DO NOTHING at the SQL level (see rbac.sql).
|
|
||||||
return s.queries.BulkAssignPermissionsToRole(ctx, dbgen.BulkAssignPermissionsToRoleParams{
|
|
||||||
RoleID: roleID,
|
|
||||||
Column2: permissionIDs,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Store) GetRolePermissions(ctx context.Context, roleID int64) ([]domain.Permission, error) {
|
func (s *Store) GetRolePermissions(ctx context.Context, roleID int64) ([]domain.Permission, error) {
|
||||||
rows, err := s.queries.GetRolePermissions(ctx, roleID)
|
rows, err := s.queries.GetRolePermissions(ctx, roleID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,15 @@ func (s *Service) SeedDefaultRolePermissions(ctx context.Context) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert missing permissions without wiping existing role permissions.
|
existing, err := s.store.GetRolePermissions(ctx, role.ID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("check existing permissions for %s: %w", roleName, err)
|
||||||
|
}
|
||||||
|
if len(existing) > 0 {
|
||||||
|
s.logger.Info("role already has permissions, skipping seed", "role", roleName, "count", len(existing))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
var permIDs []int64
|
var permIDs []int64
|
||||||
for _, key := range permKeys {
|
for _, key := range permKeys {
|
||||||
perm, err := s.store.GetPermissionByKey(ctx, key)
|
perm, err := s.store.GetPermissionByKey(ctx, key)
|
||||||
|
|
@ -87,14 +95,12 @@ func (s *Service) SeedDefaultRolePermissions(ctx context.Context) error {
|
||||||
permIDs = append(permIDs, perm.ID)
|
permIDs = append(permIDs, perm.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(permIDs) == 0 {
|
if len(permIDs) > 0 {
|
||||||
continue
|
if err := s.store.SetRolePermissions(ctx, role.ID, permIDs); err != nil {
|
||||||
|
return fmt.Errorf("seed permissions for role %s: %w", roleName, err)
|
||||||
}
|
}
|
||||||
|
s.logger.Info("seeded default permissions for role", "role", roleName, "count", len(permIDs))
|
||||||
if err := s.store.AddRolePermissions(ctx, role.ID, permIDs); err != nil {
|
|
||||||
return fmt.Errorf("seed role permissions for %s: %w", roleName, err)
|
|
||||||
}
|
}
|
||||||
s.logger.Info("ensured default permissions for role", "role", roleName, "count", len(permIDs))
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user