6.8 KiB
6.8 KiB
STEP 8 — 컨트롤러 추가 (ExperionFastController)
사전 확인 (작업 전 반드시 수행)
src/Web/Controllers/ExperionControllers.cs파일을 열어 전체 내용을 읽는다.- 아래 항목을 확인하고 기록한다:
- STEP 7이 완료되어
ExperionFastService가 빌드되는가? ExperionFastController클래스가 이미 존재하는가? → 있으면 내용 비교 후 누락 엔드포인트만 추가PinRequestrecord가 이미 존재하는가?- 파일 상단에
using Microsoft.AspNetCore.Mvc;가 있는가?
- STEP 7이 완료되어
작업 내용
파일: src/Web/Controllers/ExperionControllers.cs
위치: 파일 하단 (기존 컨트롤러 마지막 클래스 아래)
// ── FastTable / FastRecord ────────────────────────────────────────────────────
[ApiController]
[Route("api/fast")]
public class ExperionFastController : ControllerBase
{
private readonly IExperionFastService _fastSvc;
public ExperionFastController(IExperionFastService fastSvc)
=> _fastSvc = fastSvc;
/// <summary>새 fastSession 시작</summary>
[HttpPost("start")]
public async Task<IActionResult> Start([FromBody] FastSessionStartRequest request)
{
try
{
var session = await _fastSvc.StartSessionAsync(request);
return Ok(new { id = session.Id, name = session.Name, status = session.Status, startedAt = session.StartedAt });
}
catch (ArgumentException ex) { return BadRequest(new { error = ex.Message }); }
catch (InvalidOperationException ex) { return Conflict(new { error = ex.Message }); }
}
/// <summary>세션 중지</summary>
[HttpPost("{id:int}/stop")]
public async Task<IActionResult> Stop(int id)
{
try
{
await _fastSvc.StopSessionAsync(id);
return Ok(new { success = true, message = "세션이 중지되었습니다." });
}
catch (InvalidOperationException ex) { return NotFound(new { error = ex.Message }); }
}
/// <summary>세션 목록 조회</summary>
[HttpGet("sessions")]
public async Task<IActionResult> GetSessions()
{
var sessions = await _fastSvc.GetSessionsAsync();
return Ok(new
{
total = sessions.Count(),
items = sessions.Select(s => new
{
id = s.Id,
name = s.Name,
status = s.Status,
samplingMs = s.SamplingMs,
durationSec = s.DurationSec,
tagCount = s.TagList.Length,
rowCount = s.RowCount,
startedAt = s.StartedAt,
endedAt = s.EndedAt,
retentionDays = s.RetentionDays,
pinned = s.Pinned
})
});
}
/// <summary>세션 상세 정보</summary>
[HttpGet("{id:int}")]
public async Task<IActionResult> GetSession(int id)
{
var session = await _fastSvc.GetSessionAsync(id);
if (session == null) return NotFound();
return Ok(new
{
id = session.Id,
name = session.Name,
status = session.Status,
samplingMs = session.SamplingMs,
durationSec = session.DurationSec,
tagList = session.TagList,
rowCount = session.RowCount,
startedAt = session.StartedAt,
endedAt = session.EndedAt,
retentionDays = session.RetentionDays,
pinned = session.Pinned
});
}
/// <summary>레코드 조회 (Long 포맷)</summary>
[HttpGet("{id:int}/records")]
public async Task<IActionResult> GetRecords(int id,
[FromQuery] DateTime? from,
[FromQuery] DateTime? to,
[FromQuery] string format = "long")
{
var result = await _fastSvc.GetRecordsAsync(id, from, to, format);
return Ok(new
{
sessionId = result.SessionId,
from = result.From,
to = result.To,
tagNames = result.TagNames,
total = result.TotalCount,
items = result.Items.Select(r => new
{
sessionId = r.SessionId,
recordedAt = r.RecordedAt,
tagName = r.TagName,
value = r.Value
})
});
}
/// <summary>CSV Export (스트리밍)</summary>
[HttpGet("{id:int}/csv")]
public async Task<IActionResult> ExportCsv(int id,
[FromQuery] DateTime? from,
[FromQuery] DateTime? to)
{
var ms = new MemoryStream();
await _fastSvc.ExportCsvAsync(id, ms, from, to);
ms.Position = 0;
return File(ms, "text/csv", $"fast-{id}-{DateTime.Now:yyyyMMddHHmm}.csv");
}
/// <summary>세션 삭제</summary>
[HttpDelete("{id:int}")]
public async Task<IActionResult> Delete(int id)
{
try
{
await _fastSvc.DeleteSessionAsync(id);
return Ok(new { success = true, message = "세션이 삭제되었습니다." });
}
catch (InvalidOperationException ex) { return NotFound(new { error = ex.Message }); }
}
/// <summary>세션 고정/해제</summary>
[HttpPost("{id:int}/pin")]
public async Task<IActionResult> Pin(int id, [FromBody] PinRequest request)
{
try
{
await _fastSvc.PinSessionAsync(id, request.Pinned);
return Ok(new { success = true, pinned = request.Pinned });
}
catch (InvalidOperationException ex) { return NotFound(new { error = ex.Message }); }
}
}
public record PinRequest(bool Pinned);
사후 확인 (작업 후 반드시 수행)
ExperionControllers.cs파일을 다시 열어 추가된 컨트롤러를 읽는다.- 아래 항목을 하나씩 확인한다:
[Route("api/fast")]라우트가 맞는가?POST /start엔드포인트 존재POST /{id}/stop엔드포인트 존재GET /sessions엔드포인트 존재GET /{id}엔드포인트 존재GET /{id}/records엔드포인트 존재GET /{id}/csv엔드포인트 존재DELETE /{id}엔드포인트 존재POST /{id}/pin엔드포인트 존재 (총 8개 엔드포인트)PinRequestrecord 존재 (중복 선언 아닌지 확인)
dotnet build src/Web실행 → 에러/경고 0개 확인- 문제가 있으면 수정 후 다시 빌드 확인
완료 조건
dotnet build src/Web결과: 에러 0, 경고 0ExperionFastController8개 엔드포인트 모두 존재