mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-25 07:45:44 +00:00
fix: resolve dashboard OpenAPI integration issues
- FCRs & Transfer to Laying: add ExampleResponse field to routeMeta and inject example payloads into OpenAPI 200 responses for list and detail endpoints so dashboard consumers have concrete response shapes to work with - Chick In: enable GET /api/production/chickins/ list endpoint (was commented out); add P_ChickinsGetAll permission constant and wire it into the route; add OpenAPI spec entry with query params and example - Recording GET all: fix N+1 query bottleneck (2-3s response time) by pre-fetching approved transfer maps per PFK ID in two batch queries before the per-recording loop; add evaluatePopulationMutationStateFromCaches that uses the pre-fetched maps and caches hasAnyRecordingOnTransferTargets results by transfer ID — reducing per-page query count from ~20-40 to ~10-12 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+120
@@ -17,6 +17,8 @@ type TransferLayingRepository interface {
|
||||
IdExists(ctx context.Context, id uint) (bool, error)
|
||||
GetLatestApprovedBySourceKandang(ctx context.Context, sourceProjectFlockKandangID uint) (*entity.LayingTransfer, error)
|
||||
GetLatestApprovedByTargetKandang(ctx context.Context, targetProjectFlockKandangID uint) (*entity.LayingTransfer, error)
|
||||
GetLatestApprovedBySourceKandangs(ctx context.Context, pfkIDs []uint) (map[uint]*entity.LayingTransfer, error)
|
||||
GetLatestApprovedByTargetKandangs(ctx context.Context, pfkIDs []uint) (map[uint]*entity.LayingTransfer, error)
|
||||
|
||||
// Tambah method baru untuk query dengan filter lengkap
|
||||
GetAllWithFilters(ctx context.Context, offset int, limit int, params *GetAllFilterParams) ([]entity.LayingTransfer, int64, error)
|
||||
@@ -242,3 +244,121 @@ func (r *TransferLayingRepositoryImpl) GetLatestApprovedByTargetKandang(ctx cont
|
||||
}
|
||||
return &transfer, nil
|
||||
}
|
||||
|
||||
type pfkTransferIDRow struct {
|
||||
SourcePFKID uint `gorm:"column:source_pfk_id"`
|
||||
TransferID uint `gorm:"column:transfer_id"`
|
||||
}
|
||||
|
||||
func (r *TransferLayingRepositoryImpl) GetLatestApprovedBySourceKandangs(ctx context.Context, pfkIDs []uint) (map[uint]*entity.LayingTransfer, error) {
|
||||
result := make(map[uint]*entity.LayingTransfer)
|
||||
if len(pfkIDs) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
var rows []pfkTransferIDRow
|
||||
err := r.db.WithContext(ctx).Raw(`
|
||||
SELECT DISTINCT ON (source_pfk_id) source_pfk_id, transfer_id
|
||||
FROM (
|
||||
SELECT id AS transfer_id, source_project_flock_kandang_id AS source_pfk_id
|
||||
FROM laying_transfers
|
||||
WHERE source_project_flock_kandang_id IN ?
|
||||
AND deleted_at IS NULL
|
||||
AND (
|
||||
SELECT a.action FROM approvals a
|
||||
WHERE a.approvable_type = ? AND a.approvable_id = id
|
||||
ORDER BY a.id DESC LIMIT 1
|
||||
) = ?
|
||||
UNION ALL
|
||||
SELECT lts.laying_transfer_id AS transfer_id, lts.source_project_flock_kandang_id AS source_pfk_id
|
||||
FROM laying_transfer_sources lts
|
||||
JOIN laying_transfers t ON t.id = lts.laying_transfer_id AND t.deleted_at IS NULL
|
||||
WHERE lts.source_project_flock_kandang_id IN ?
|
||||
AND lts.deleted_at IS NULL
|
||||
AND (
|
||||
SELECT a.action FROM approvals a
|
||||
WHERE a.approvable_type = ? AND a.approvable_id = t.id
|
||||
ORDER BY a.id DESC LIMIT 1
|
||||
) = ?
|
||||
) combined
|
||||
ORDER BY source_pfk_id, transfer_id DESC
|
||||
`,
|
||||
pfkIDs, string(utils.ApprovalWorkflowTransferToLaying), string(entity.ApprovalActionApproved),
|
||||
pfkIDs, string(utils.ApprovalWorkflowTransferToLaying), string(entity.ApprovalActionApproved),
|
||||
).Scan(&rows).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(rows) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
transferIDs := make([]uint, 0, len(rows))
|
||||
pfkByTransfer := make(map[uint]uint, len(rows))
|
||||
for _, row := range rows {
|
||||
transferIDs = append(transferIDs, row.TransferID)
|
||||
pfkByTransfer[row.TransferID] = row.SourcePFKID
|
||||
}
|
||||
|
||||
var transfers []entity.LayingTransfer
|
||||
if err := r.db.WithContext(ctx).Where("id IN ? AND deleted_at IS NULL", transferIDs).Find(&transfers).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range transfers {
|
||||
if pfkID := pfkByTransfer[transfers[i].Id]; pfkID != 0 {
|
||||
result[pfkID] = &transfers[i]
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *TransferLayingRepositoryImpl) GetLatestApprovedByTargetKandangs(ctx context.Context, pfkIDs []uint) (map[uint]*entity.LayingTransfer, error) {
|
||||
result := make(map[uint]*entity.LayingTransfer)
|
||||
if len(pfkIDs) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
var rows []pfkTransferIDRow
|
||||
err := r.db.WithContext(ctx).Raw(`
|
||||
SELECT DISTINCT ON (source_pfk_id) source_pfk_id, transfer_id
|
||||
FROM (
|
||||
SELECT ltt.laying_transfer_id AS transfer_id, ltt.target_project_flock_kandang_id AS source_pfk_id
|
||||
FROM laying_transfer_targets ltt
|
||||
JOIN laying_transfers t ON t.id = ltt.laying_transfer_id AND t.deleted_at IS NULL
|
||||
WHERE ltt.target_project_flock_kandang_id IN ?
|
||||
AND ltt.deleted_at IS NULL
|
||||
AND (
|
||||
SELECT a.action FROM approvals a
|
||||
WHERE a.approvable_type = ? AND a.approvable_id = t.id
|
||||
ORDER BY a.id DESC LIMIT 1
|
||||
) = ?
|
||||
) combined
|
||||
ORDER BY source_pfk_id, transfer_id DESC
|
||||
`,
|
||||
pfkIDs, string(utils.ApprovalWorkflowTransferToLaying), string(entity.ApprovalActionApproved),
|
||||
).Scan(&rows).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(rows) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
transferIDs := make([]uint, 0, len(rows))
|
||||
pfkByTransfer := make(map[uint]uint, len(rows))
|
||||
for _, row := range rows {
|
||||
transferIDs = append(transferIDs, row.TransferID)
|
||||
pfkByTransfer[row.TransferID] = row.SourcePFKID
|
||||
}
|
||||
|
||||
var transfers []entity.LayingTransfer
|
||||
if err := r.db.WithContext(ctx).Where("id IN ? AND deleted_at IS NULL", transferIDs).Find(&transfers).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range transfers {
|
||||
if pfkID := pfkByTransfer[transfers[i].Id]; pfkID != 0 {
|
||||
result[pfkID] = &transfers[i]
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user