一键导入
ingredient-management
식재료 관리 도메인 모델 — 보관 위치·카테고리·소비기한·수량 관리 패턴. PWA 오프라인 앱용 로컬 상태 설계 포함.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
식재료 관리 도메인 모델 — 보관 위치·카테고리·소비기한·수량 관리 패턴. PWA 오프라인 앱용 로컬 상태 설계 포함.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Spring Security 5.5.x + jjwt 0.10.7 레거시 JWT 인증 - WebSecurityConfigurerAdapter, OncePerRequestFilter, javax.servlet 환경
Spring Boot 3.x + Spring Security 6.x + jjwt 0.12.x 기반 모던 JWT 인증 패턴. SecurityFilterChain Bean, 람다 DSL, jakarta.servlet, Virtual Threads 적용
Unity 6 LTS 2D 모바일 게임용 uGUI 시스템 전문 스킬. Canvas/RectTransform/TextMeshPro, 모바일 UI 패턴(팝업·무한 스크롤·광고·IAP), 성능 최적화, UI Toolkit과의 선택 기준 포함.
아크라시아(akrasia, 자제력 없음) 학술 논쟁의 핵심 구도와 주요 연구자·문헌을 빠르게 파악할 수 있는 도메인 지식 스킬. 도덕윤리교육 전공 대학원생(석/박사)이 학위논문·KCI 투고·세미나 준비 시 고대–현대–한국 학계–도덕심리학 흐름을 한 번에 짚도록 구성. <example>사용자: "아리스토텔레스의 propeteia와 astheneia 구분을 인용하려는데 출처를 알려줘"</example> <example>사용자: "데이비슨이 의지박약을 어떻게 가능하다고 봤는지 핵심 논증을 정리해줘"</example> <example>사용자: "한국 도덕교육 학계에서 아크라시아 다룬 논문 있어?"</example>
아리스토텔레스 『니코마코스 윤리학』에서 akrasia(자제력없음)와 akolasia(무절제)의 5축 차이를 정밀하게 정리한 학위논문 자료 스킬. NE VII.4 1147b20-1148b14, VII.8 1150b29-1151a28, III.10-12 1117b23-1119b18 절별 분해와 표준 학자 해석(Bostock, Broadie-Rowe, Pakaluk, Hursthouse, Charles 등)을 포함. 도덕교육 적용을 위한 두 상태 차이의 함의 및 한국어 번역어 처리 권장안 제공. <example>사용자: "akrates와 akolastos를 prohairesis 측면에서 어떻게 구분해야 하나요?"</example> <example>사용자: "NE VII.4의 ἁπλῶς akrasia가 akolasia와 어떻게 갈라지는지 절별 분해해주세요"</example> <example>사용자: "Hursthouse의 연속체 모델을 도덕교육 적용 절에서 어떻게 활용할 수 있나요?"</example>
한국 위기 대응 자원(자살·자해·정신건강·여성·청소년·노인·다문화) 핫라인과 앱·챗봇 안전 가드 응답 패턴 종합. 꿈 해몽·정신건강 앱 등 자가 진단/감정 콘텐츠 도메인에서 위험 신호 포착 시 안전한 자원 안내 문구를 작성할 때 참조. <example>사용자: "꿈 해몽 앱에 위기 안내 문구를 어떻게 넣을까?"</example> <example>사용자: "한국에서 자살예방 핫라인 번호가 어떻게 바뀌었지?"</example> <example>사용자: "정신건강 챗봇 안전 가드 응답 템플릿을 짜줘"</example>
| name | ingredient-management |
| description | 식재료 관리 도메인 모델 — 보관 위치·카테고리·소비기한·수량 관리 패턴. PWA 오프라인 앱용 로컬 상태 설계 포함. |
소스: 국내 식재료 관리 앱(유통기한 언제지·원더 프리지·BEEP) 도메인 분석 검증일: 2026-06-26
interface Ingredient {
id: string; // UUID
name: string; // 식재료명 (예: "닭가슴살")
category: IngredientCategory; // 식품 분류
storageLocation: StorageLocation; // 보관 위치
quantity: number; // 수량
unit: IngredientUnit; // 단위
purchaseDate: string; // 구매일 (ISO 8601)
expiryDate?: string; // 소비기한 (없으면 undefined)
memo?: string; // 메모
createdAt: string;
updatedAt: string;
}
type IngredientCategory =
| 'grain' // 곡류·서류 (쌀, 감자, 고구마)
| 'vegetable' // 채소류
| 'fruit' // 과일류
| 'meat' // 육류
| 'seafood' // 어패류
| 'egg_dairy' // 난류·유제품
| 'bean_nut' // 콩류·견과류
| 'processed' // 가공식품
| 'sauce' // 양념·소스
| 'other'; // 기타
type StorageLocation =
| 'fridge' // 냉장
| 'freezer' // 냉동
| 'pantry' // 상온 (식료품 창고·찬장)
| 'counter'; // 실온 (바나나·토마토 등)
type IngredientUnit =
| 'g' // 그램
| 'kg' // 킬로그램
| 'ml' // 밀리리터
| 'l' // 리터
| 'ea' // 개 (개수)
| 'pack' // 팩
| 'can' // 캔
| 'bag'; // 봉지
type IngredientStatus =
| 'fresh' // 신선 (소비기한 7일 이상)
| 'warning' // 임박 (소비기한 3~7일)
| 'urgent' // 주의 (소비기한 3일 이내)
| 'expired' // 만료
| 'no_expiry'; // 소비기한 없음 (장기 보관 가능)
const getIngredientStatus = (ingredient: Ingredient): IngredientStatus => {
if (!ingredient.expiryDate) return 'no_expiry';
const today = new Date();
const expiry = new Date(ingredient.expiryDate);
const daysLeft = Math.ceil((expiry.getTime() - today.getTime()) / (1000 * 60 * 60 * 24));
if (daysLeft < 0) return 'expired';
if (daysLeft <= 3) return 'urgent';
if (daysLeft <= 7) return 'warning';
return 'fresh';
};
| 식재료 | 냉장 | 냉동 | 상온 |
|---|---|---|---|
| 생닭 | 2일 | 9개월 | — |
| 소·돼지고기 | 3~5일 | 4~6개월 | — |
| 생선(생) | 1~2일 | 6개월 | — |
| 달걀 | 3~5주 | — | 1~2주 |
| 우유 | 개봉 후 5~7일 | — | — |
| 배추김치 | 1~2개월 | 6개월 | — |
| 밥 | 3~4일 | 1개월 | — |
| 감자·고구마 | 1~2주 | — | 1~2주 (서늘한 곳) |
| 양파 | 1~2개월 | — | 1~2개월 |
| 마늘 | 3개월 | 6~12개월 | 2~4주 |
주의: 위 수치는 일반적인 참고값이며 개봉·조리 여부에 따라 달라짐
// Dexie 스키마
class FridgeDatabase extends Dexie {
ingredients!: Table<Ingredient>;
constructor() {
super('FridgeDB');
this.version(1).stores({
// 인덱스: id(primary), category, storageLocation, expiryDate
ingredients: '++id, category, storageLocation, expiryDate',
});
}
}
// 소비기한 임박 순 정렬
const getSortedByExpiry = () =>
db.ingredients
.where('expiryDate')
.above('') // expiryDate 있는 것만
.sortBy('expiryDate');
// 위치별 필터
const getByLocation = (location: StorageLocation) =>
db.ingredients.where('storageLocation').equals(location).toArray();
// 카테고리별 필터
const getByCategory = (category: IngredientCategory) =>
db.ingredients.where('category').equals(category).toArray();
// 전체 (소비기한 만료 제외)
const getAvailable = async () => {
const all = await db.ingredients.toArray();
const today = new Date().toISOString().split('T')[0];
return all.filter(i => !i.expiryDate || i.expiryDate >= today);
};
식단 추천 AI에 넘길 식재료 컨텍스트 포맷:
const buildIngredientContext = async (): Promise<string> => {
const available = await getAvailable();
// 상태별 그룹핑
const urgent = available.filter(i => getIngredientStatus(i) === 'urgent');
const warning = available.filter(i => getIngredientStatus(i) === 'warning');
const fresh = available.filter(i =>
['fresh', 'no_expiry'].includes(getIngredientStatus(i))
);
const format = (items: Ingredient[]) =>
items.map(i => `${i.name} (${i.quantity}${i.unit})`).join(', ');
return `
[빨리 써야 하는 식재료 (3일 이내)]
${urgent.length > 0 ? format(urgent) : '없음'}
[곧 사용해야 하는 식재료 (7일 이내)]
${warning.length > 0 ? format(warning) : '없음'}
[보유 중인 식재료]
${fresh.length > 0 ? format(fresh) : '없음'}
`.trim();
};
| 카테고리 | 이모지 | 한글명 |
|---|---|---|
| grain | 🌾 | 곡류·서류 |
| vegetable | 🥦 | 채소류 |
| fruit | 🍎 | 과일류 |
| meat | 🥩 | 육류 |
| seafood | 🐟 | 어패류 |
| egg_dairy | 🥚 | 난류·유제품 |
| bean_nut | 🫘 | 콩류·견과류 |
| processed | 🥫 | 가공식품 |
| sauce | 🧂 | 양념·소스 |
| other | 📦 | 기타 |
| 상황 | 트리거 시점 | 알림 내용 |
|---|---|---|
| 소비기한 임박 | D-3, D-1 | "[식재료명] 소비기한이 N일 남았어요" |
| 소비기한 당일 | D-day | "[식재료명] 오늘까지 사용하세요" |
| 재고 부족 | quantity ≤ 임계값 | "[식재료명] 재고가 얼마 남지 않았어요" |