Files
superport_v2/AGENTS.md
JiWoong Sul d76f765814 feat(approvals): Approval Flow v2 프런트엔드 전면 개편
- 환경/라우터 모듈에 approval_flow_v2 토글을 추가하고 FeatureFlags 초기화를 연결 (.env*, lib/core/**)
- ApiClient 빌더·ApiRoutes 확장과 ApprovalRepositoryRemote 리팩터링으로 include·액션 시그니처를 정합화
- ApprovalFlow·ApprovalDraft 엔티티/레포/유즈케이스를 도입해 서버 초안과 단계 액션(승인·회수·재상신)을 지원
- Approval 컨트롤러·히스토리·템플릿 페이지와 공유 위젯을 재작성해 감사 로그·회수 UX·템플릿 CRUD를 반영
- Inbound/Outbound/Rental 컨트롤러·페이지에 결재 섹션을 삽입하고 대시보드 pending 카드 요약을 갱신
- SuperportDialog·FormField 등 공통 위젯을 보강하고 승인 위젯 가이드를 추가해 UI 가이드를 정리
- 결재/재고 테스트 픽스처와 단위·위젯·통합 테스트를 확장하고 flutter_test_config로 스테이징 호스트를 허용
- Approval Flow 레포트/플랜 문서를 업데이트하고 ApprovalFlow_System_Integration_and_ChangePlan.md를 추가
- 실행: flutter analyze, flutter test
2025-10-31 01:05:39 +09:00

124 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Repository Guidelines
## Project Structure & Module Organization
Place all Flutter source in `lib/`, keeping cross-cutting pieces in `lib/core/` (config, constants, services) and feature screens under `lib/features/<domain>/`. Shared widgets and theming go in `lib/widgets/` and `lib/theme/`. Tests mirror this layout in `test/` and, when browser flows matter, `integration_test/`. Static specs, including the UI breakdown in `doc/입출고 대여 폼 정리.md`, stay in `doc/`. Keep assets in `assets/` and register them inside `pubspec.yaml`.
## Build, Test, and Development Commands
- `flutter pub get` — install or refresh package dependencies.
- `flutter analyze` — static analysis; treat warnings as blockers before review.
- `flutter test` — run the unit/widget suite; add `--coverage` when validating overall health.
- `flutter run -d chrome --web-renderer canvaskit` — local web run matching production rendering.
- `dart run build_runner build --delete-conflicting-outputs` — regenerate freezed/json_serializable files when models change.
- After every code addition, modification, or deletion, run both `flutter analyze` and `flutter test` before considering the task complete.
## Coding Style & Naming Conventions
Use Flutters two-space indentation and run `dart format .` before committing. Follow the Clean Architecture layering: DTOs/remote in `data`, domain interfaces/use cases in `domain`, controllers/widgets in presentation. File names use `snake_case.dart`; classes use `UpperCamelCase`; methods and fields use `lowerCamelCase`. Prefer `const` constructors/widgets, and use `shadcn_ui` components (especially `ShadTable`) for new screens. Register dependencies in `lib/injection_container.dart` via `get_it`.
## Testing Guidelines
Each feature ships with unit tests (`*_test.dart`) living beside the source module. Widget tests should verify key flows like list rendering and form validation; leverage `WidgetTester` with fake data. Integration scenarios covering navigation across the inventory, approval, and reporting flows belong in `integration_test/`. Target meaningful coverage (≈70% per feature) and ensure CI-friendly seeds by avoiding real API calls.
## Commit & Pull Request Guidelines
Commits follow the existing Superport convention: Korean imperative summaries with optional English technical nouns, e.g., `"대여 상세 테이블 정렬 수정"`. For PRs, include (1) a concise summary of user-visible impact, (2) screenshots or GIFs for UI changes, (3) linked issue or JIRA reference, and (4) verification notes (commands run, tests passing). Squash before merge unless release tagging requires history.
## Change Comment Guidelines
- Document every change with a Conventional Commit style summary line: `type(scope): <summary in Korean>`. Use Korean imperatives for the message body while keeping the scope in English (module/package).
- Follow the summary with a blank line and bullet points that detail the concrete modifications, each starting with `- ` and phrased in past-tense or imperative sentences that mention impacted modules.
- Include tests, scripts, and document updates in the bullet list so reviewers understand coverage.
- When multiple subsystems change, group bullets logically (e.g., backend, frontend, docs) and keep each bullet under 120 characters.
- Example:
```
feat(api): 헬스체크에 빌드 메타데이터 노출
- BUILD_VERSION 환경변수를 우선으로 사용하고 git 커밋 해시를 fallback으로 설정하는 build.rs를 추가
- 헬스체크 응답에 빌드 버전을 포함하고 pagination 쿼리 파싱을 위해 serde_urlencoded를 도입하여 테스트를 보강
- 원격 배포 스크립트에서 BUILD_VERSION을 로컬/원격 실행에 전달하고 문서를 최신 플로우로 업데이트
```
## Architecture & Environment Notes
Initialize environments via `.env.development` / `.env.production` and load them through `Environment.initialize()` before bootstrapping DI. New data sources should expose repository interfaces in `domain/` and rely on the shared `ApiClient` instance. Do not use mock data in the application; always call the real backend (staging/production as appropriate). If an endpoint is not available, mark the feature as disabled behind a feature flag rather than mocking.
- Frontend behaviour/data models must strictly follow the deployed backend contract. If a required endpoint is missing, request a backend fix rather than introducing mock data.
---
## Language & Communication Policy
- This document (AGENTS.md) and repository guidelines are written in English.
- Assistant responses to users (conversations, task summaries, PR descriptions) must be in Korean by default, unless the user explicitly requests English.
- Code comments must be written in Korean (see “Commenting Policy — Korean”).
- User-facing UI copy is Korean-first unless a requirement states otherwise.
- Identifiers (class/variable/function/file names) remain in English following the naming conventions above.
---
## Notification Policy
- Run `notify.py` right before delivering the final wrap-up report or ending the conversation so the notification is sent at task completion.
- Use the `notify.py` script located at `/Users/maximilian.j.sul/.codex/notify.py`.
- Update relevant progress documents when a task is completed (e.g., `doc/approval_flow_frontend_task_plan.md`).
---
## SRP & Clean Architecture Enforcement
Apply these principles repo-wide. Use the checklist below during reviews.
- Single Responsibility Principle (SRP)
- A class/file must have exactly one reason to change.
- In widgets, separate layout/rendering from state/event handling. Move complex logic to controllers/use cases.
- Extract form validation, transformations/mapping, sorting/filtering into dedicated utilities/services.
- Avoid god pages/widgets (split when file > 400 LOC or a build method > 200 LOC).
- Clean Architecture boundaries
- presentation: views/controllers/state (view models). No business rules or direct data access.
- domain: entities, repository interfaces, use cases. No framework dependencies.
- data: DTOs and data sources (API/local) implementing domain interfaces. Never depend on presentation.
- DI: wire dependencies only in `lib/injection_container.dart`. No cross-layer back references.
- Dependency rule
- Allowed direction is presentation → domain → data; never the reverse.
- domain must not depend on `flutter/*`, `shadcn_ui`, or any UI packages.
- data must not reference presentation. Convert DTOs to domain entities before exposing.
- UI composition (shadcn_ui)
- Lists: standardize on `ShadTable`-based components; keep table/column specs in dedicated classes.
- Forms: separate field widgets, validation logic, and dialog layout; manage form state in a controller.
- Modals: use `SuperportShadDialog` consistently with header/body/footer sections.
- Testing
- presentation: widget tests for rendering, interactions, and validation messages.
- domain: unit tests for use-case scenarios.
- data: contract tests for JSON mapping; never hit real network endpoints.
## Networking Stack Guidelines
- Use a single `ApiClient` (Dio wrapper) for all HTTP calls; do not instantiate raw `Dio` per feature.
- Initialize env via `Environment.initialize()` before DI, then register `ApiClient` in `lib/injection_container.dart` and inject into repositories.
- Attach `AuthInterceptor` to handle token injection and 401 → refresh → retry. On refresh failure, clear session and navigate to login.
- Standardize query params: `page`, `page_size`, `q`, `sort`, `order`, `updated_since`, `include`.
- Keep logging in development only and redact secrets (tokens/cookies).
## Commenting Policy — Korean
- Write comments in Korean for all public APIs, core logic, and business rules.
- Public classes/methods: use `///` doc comments in Korean (purpose, parameters, returns, exceptions, examples).
- Complex branches/math/performance: use `//` line comments to explain intent and rationale.
- Prefer Korean domain terms; include the English term in parentheses on first mention (e.g., 결재(approval)).
- Dont: add meaningless comments, let comments drift from code, or mix excessive English.
- Do: document invariants, preconditions, side effects, and failure scenarios explicitly.
## File/Function Size Guidelines
- Files over ~400 LOC: consider splitting (widgets/controllers/utils).
- Functions over ~60 LOC: refactor into private helpers.
- Widget tree nesting > 5 levels: extract sub-widgets.
## Review Checklist (SRP/Clean)
- [ ] Does this file/class have exactly one reason to change?
- [ ] Are business rules absent from presentation?
- [ ] Does the domain layer avoid dependencies on frameworks/UI packages?
- [ ] Does the data layer avoid referencing presentation?
- [ ] Is DI centralized in `lib/injection_container.dart`?
- [ ] Are validation/transforms/sort/filter extracted into utilities/services?
- [ ] Are comments written in Korean and do they clearly cover intent/constraints/failure cases?