package repository import ( "context" "database/sql" "fmt" "git.godopu.com/lab/landing_page/backend/internal/models" ) type StandardizationRepository struct { db *sql.DB } func NewStandardizationRepository(db *sql.DB) *StandardizationRepository { return &StandardizationRepository{db: db} } func (r *StandardizationRepository) GetStandardsBodiesWithProjects(ctx context.Context) ([]models.StandardsBodyWithProjects, error) { // Query bodies ordered by display_order bodyQuery := ` SELECT id, org, full_name, scope, period, role, display_order FROM standards_bodies ORDER BY display_order ASC, id ASC ` bodyRows, err := r.db.QueryContext(ctx, bodyQuery) if err != nil { return nil, fmt.Errorf("query standards bodies: %w", err) } defer bodyRows.Close() var bodies []models.StandardsBodyWithProjects bodyMap := make(map[int]int) // body_id -> index in bodies for bodyRows.Next() { var b models.StandardsBodyWithProjects if err := bodyRows.Scan(&b.ID, &b.Org, &b.FullName, &b.Scope, &b.Period, &b.Role, &b.DisplayOrder); err != nil { return nil, fmt.Errorf("scan standards body: %w", err) } b.Projects = []models.StandardProjectGroup{} bodyMap[b.ID] = len(bodies) bodies = append(bodies, b) } if err := bodyRows.Err(); err != nil { return nil, err } // Query documents ordered by body_id, and preserves curated insertion order with MIN(id) ASC docQuery := ` SELECT id, body_id, wg, project_name, title, doc_ref, status, published_at FROM standard_documents ORDER BY body_id ASC, id ASC ` docRows, err := r.db.QueryContext(ctx, docQuery) if err != nil { return nil, fmt.Errorf("query standard documents: %w", err) } defer docRows.Close() // Group documents into projects under each body preserving curated order type projectKey struct { bodyID int wg string projectName string } projectMap := make(map[projectKey]int) // projectKey -> index in bodies[bIdx].Projects for docRows.Next() { var d models.StandardDocument if err := docRows.Scan(&d.ID, &d.BodyID, &d.WG, &d.ProjectName, &d.Title, &d.DocRef, &d.Status, &d.PublishedAt); err != nil { return nil, fmt.Errorf("scan standard document: %w", err) } bIdx, bodyExists := bodyMap[d.BodyID] if !bodyExists { continue } key := projectKey{bodyID: d.BodyID, wg: d.WG, projectName: d.ProjectName} pIdx, projExists := projectMap[key] if !projExists { pIdx = len(bodies[bIdx].Projects) bodies[bIdx].Projects = append(bodies[bIdx].Projects, models.StandardProjectGroup{ WG: d.WG, Name: d.ProjectName, Documents: []models.StandardDocument{}, }) projectMap[key] = pIdx } bodies[bIdx].Projects[pIdx].Documents = append(bodies[bIdx].Projects[pIdx].Documents, d) } return bodies, docRows.Err() }