Files
Gnuboard7/app/Support/ApiDoc/ColumnCommentResolver.php
HeuJung 70452745c4 feat(api-docs): API 레퍼런스 문서 전면화 — 추출 파이프라인·전 대상 문서화·audit 강제
코드에만 존재하던 REST API 계약(약 663 엔드포인트)을 코어/확장 책임별로
분리된 마크다운 레퍼런스로 전면 문서화한다. 674개 규모에서 수기 문서는
반드시 drift 하므로 "코드 추출 → 스캐폴딩 → 사람이 서술 채움 → 하네스가
커버리지 강제" 하이브리드로 구성했다.

추출 파이프라인 (app/Support/ApiDoc):
- ApiRouteInventory / FormRequestIntrospector / ApiEndpointProbe(실측 HTTP) /
 ResponseSchemaInferrer / ApiDocScaffolder / ColumnCommentResolver /
 ResourceFieldDescriber / ParameterDescriber
- api:docgen 커맨드(--scope/--seed/--check/--dry-run/--base-url/--user) +
 응답/파라미터 in-place 백필 커맨드 2종(재생성 없이 TODO 셀만 치환, 멱등)
- ApiDocSampleSeeder 계약 + 코어/확장 시더로 실측용 완전 샘플 멱등 생성

문서화 (실측 기반, GET read-only 실호출):
- 코어 291엔드포인트 35파일(docs/backend/api) + 규정 docs/backend/api-documentation.md
- 확장: ecommerce(231)·board(80)·page(17)·hello_module(2)·pay_kginicis(22)·
 gdpr(15)·ckeditor5(2)·marketing(2)·verification_kginicis(1)
- 표준 4구성(헤더·요청 파라미터·응답 필드·에러 표) + 엔드포인트 용도 서술
- 파라미터 용도·응답 필드 설명 셀 전수 채움(도메인 지식 수기)

하네스:
- audit 룰 api-doc-coverage — API 표면(라우트/컨트롤러/FormRequest/Resource)
 변경 시 대응 문서 미동반이면 차단. 전 대상 문서 완비로 error 승격
- file-rules 리마인더(컨트롤러/라우트 편집 시), coverage.json, dev-dashboard 카드
- docs/backend/routing.md 확장 공개 API URL 스킴 정정(/api/modules|plugins/{id})
- /AGENTS.md/docs-index 동기
2026-07-08 18:22:33 +09:00

72 lines
2.0 KiB
PHP

<?php
namespace App\Support\ApiDoc;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Schema;
/**
* 컬럼 주석 해석기
*
* 모델 테이블의 컬럼 주석(한국어 comment) 을 조회해 응답 필드 설명의 기본값으로
* 제공합니다. G7 은 마이그레이션 한국어 comment 를 필수화하므로, 이 주석이 필드
* 설명의 SSoT 가 됩니다. 정적 스키마 조회이므로 실측 없이도 동작합니다.
*/
class ColumnCommentResolver
{
/**
* @var array<string, array<string, string>> 테이블별 컬럼 주석 캐시
*/
private array $cache = [];
/**
* 모델 테이블의 컬럼명 => 주석 맵을 반환합니다.
*
* @param class-string|null $modelClass 모델 FQCN
* @return array<string, string> 컬럼명 => 주석
*/
public function forModel(?string $modelClass): array
{
if (! $modelClass || ! class_exists($modelClass) || ! is_subclass_of($modelClass, Model::class)) {
return [];
}
try {
$table = (new $modelClass)->getTable();
} catch (\Throwable) {
return [];
}
return $this->forTable($table);
}
/**
* 테이블의 컬럼명 => 주석 맵을 반환합니다 (캐시).
*
* @param string $table 테이블명
* @return array<string, string> 컬럼명 => 주석
*/
public function forTable(string $table): array
{
if (isset($this->cache[$table])) {
return $this->cache[$table];
}
$map = [];
try {
foreach (Schema::getColumns($table) as $column) {
$comment = $column['comment'] ?? null;
if (is_string($comment) && $comment !== '') {
$map[$column['name']] = $comment;
}
}
} catch (\Throwable) {
// 테이블 부재/드라이버 미지원 시 빈 맵
}
return $this->cache[$table] = $map;
}
}