나리
전시만드는 방식문의
←블로그 목록
개발 일지2026-07-14Mazzucchi 주문관리 시스템

코모 호수 옆 3대째 정육점에 앱이 생겼습니다

전화와 메모장으로 돌아가던 가족의 가게. 이탈리아 정육점 Macelleria Mazzucchi에 주문 앱을 만들게 된 사연과, 만들면서 배운 것들을 적었습니다.

이야기가족다국어Flutter
3대가족이 이어온 세월
10개 언어이탈리아어부터 한국어까지
100g주문 단위
10분픽업 슬롯 간격

코모 호수 옆의 작은 가게

이탈리아 북부, 코모 호수 바로 옆 동네에 작은 정육점이 하나 있습니다. Macelleria Mazzucchi. 같은 가족이 3대째 하고 있는 가게입니다.

관광지 옆 가게라고 하면 기념품 가게 같은 걸 떠올리기 쉬운데, 여기는 분위기가 좀 다릅니다. 여름 휴가철이나 크리스마스 시즌이 되면 가게 앞에 스위스, 독일, 프랑스, 영국 번호판을 단 차들이 섭니다. 호수 구경 왔다가 들르는 사람도 있지만, 여기 고기를 사겠다고 국경을 넘어오는 사람들이 진짜로 있습니다. 3대 동안 쌓인 단골이란 그런 겁니다.

그리고 저한테 이 가게는 남의 가게가 아닙니다. 가족의 가게입니다. 그래서 이 프로젝트에는 의뢰서도 계약서도 없습니다. 시작은 저녁 식탁이었습니다.

전화벨과 메모장

가게의 하루를 옆에서 보고 있으면, 주문은 거의 다 전화로 들어옵니다. 사장님은 고기를 썰다 말고 장갑을 벗고 전화를 받습니다. 부위와 중량을 듣고 계산대 옆 메모장에 적습니다. 그리고 다시 장갑을 끼고 하던 일로 돌아갑니다.

이 방식으로도 가게는 3대를 잘 굴러왔습니다. 그런데 옆에서 지켜보다 보니 자꾸 같은 장면이 눈에 밟혔습니다.

  • 바쁜 시간에는 손을 뗄 수가 없어서 전화를 그냥 놓칩니다. 그 주문이 어디로 갔는지는 아무도 모릅니다.
  • 전화로 부위 이름을 주고받다 보면 서로 다른 걸 알아들은 채로 통화가 끝나는 날이 있습니다.
  • 오늘 장사가 어땠는지 궁금하면 영수증 뭉치를 처음부터 넘겨봐야 합니다.

외국 손님에게는 문턱이 하나 더 있습니다. 전화 주문을 하려면 이탈리아어로 부위 이름을 설명해야 하니까요.

💡 문제는 기술이 아니었습니다

이 가게에 필요한 건 "디지털 전환" 같은 거창한 게 아니었습니다. 전화벨이 울리는 사이에 새어 나가던 것들 — 주문 하나, 손님 한 명, 저녁의 여유 — 을 도로 찾아오는 일이었습니다.

그래서 앱을 만들었습니다

하나의 코드베이스에서 앱 두 개를 만들었습니다.

손님용 앱에서는 부위를 고르고, 중량을 100g 단위로 정하고, 픽업 시간을 10분 단위 슬롯으로 예약합니다. 전화 한 통 없이도 "내일 오전 10시 10분, 등심 800g"이 토씨 하나 안 틀리고 전달됩니다.

사장님 앱에는 가게 돌아가는 방식을 그대로 담았습니다. 슬롯마다 받을 수 있는 주문 수, 영업시간과 점심 휴식, 일요일 휴무, 바쁜 날 특정 시간대 잠그기까지. 가게가 앱에 맞추는 게 아니라 앱이 가게에 맞춥니다.

정육점다운 구석도 있습니다. 고기는 공산품이 아니라서, 800g을 주문해도 칼이 정확히 800g에서 멈추지 않습니다. 그래서 주문할 때 보이는 금액은 어디까지나 "예상 금액"이고, 사장님이 실제로 썬 무게를 입력해야 최종 금액이 정해집니다. 손님은 픽업하면서 그 금액을 냅니다. 동네 정육점에서 늘 하던 방식 그대로, 저울이 마지막 말을 하는 구조입니다.

새 주문이 들어오면 사장님 휴대폰이 울리고, 주문이 준비되면 손님 휴대폰이 울립니다. 이제 전화벨 대신 알림이 웁니다.

열 가지 언어를 하는 정육점

손님용 앱에서 언어 목록을 열면 이탈리아어부터 영어, 독일어, 프랑스어, 스페인어, 네덜란드어, 포르투갈어, 일본어, 중국어, 한국어까지 열 개가 나옵니다. 동네 정육점 앱치고는 과하다 싶지만, 손님 명단을 보면 고개가 끄덕여집니다. 스위스에서, 독일에서, 프랑스에서, 영국에서 호수를 건너오는 분들이니까요.

언어를 바꾸면 버튼 문구만 바뀌는 게 아닙니다. 부위 이름과 설명까지 전부 번역 테이블로 관리하기 때문에, 같은 진열대가 프랑스 손님에게는 Entrecôte de bœuf로, 독일 손님에게는 Rinder-Ribeye로 보입니다. 가게 이름마저 Boucherie가 됐다가 Metzgerei가 됩니다.

프랑스어 메뉴 화면 — Boucherie Mazzucchi
프랑스 손님의 화면 — Boucherie Mazzucchi, Entrecôte de bœuf
독일어 메뉴 화면 — Metzgerei Mazzucchi
독일 손님의 화면 — Metzgerei Mazzucchi, Rinder-Ribeye

그럼 한국어는? 솔직히 말하겠습니다. 제가 편하려고 넣었습니다. 이탈리아 정육점 앱을 만드는 한국인 개발자도, 테스트할 때만큼은 모국어가 그립습니다. 덕분에 이 가게는 아마 코모 호수를 통틀어 한국어가 되는 유일한 정육점일 겁니다.

✅ 언어 추가는 코드가 아니라 데이터

상품명과 카테고리명을 하드코딩하지 않고 처음부터 번역 테이블(product_translations)에 뒀습니다. 언어를 하나 더 붙이는 건 코드 수정이 아니라 데이터 추가고, 아직 번역이 없는 상품은 조용히 이탈리아어로 돌아갑니다. 메뉴가 깨지는 일은 없습니다.

오래된 가게에 앱을 들이는 일

이 프로젝트에서 제일 조심한 건 기술이 아니라 가게의 리듬을 건드리지 않는 것이었습니다.

3대를 이어온 가게에는 이미 완성된 리듬이 있습니다. 아침에 문을 열고, 점심에 쉬고, 일요일에 쉬고, 단골이 뭘 좋아하는지 기억하는 리듬. 앱이 할 일은 그 리듬을 바꾸는 게 아니라 거드는 것이었습니다. 그래서 사장님 앱의 설정 화면에는 "영업시간", "점심 휴식", "휴무일", "슬롯 잠금" 같은, 가게 하는 사람의 말로 된 항목들만 들어 있습니다.

전화벨은 지금도 울립니다. 오래된 단골들은 여전히 전화로 주문하고, 그건 그것대로 좋습니다. 달라진 게 있다면 메모장 옆에 앱이 하나 생겼다는 것, 그리고 국경을 넘어온 손님도, 이탈리아어가 서툰 손님도, 이제 같은 카운터 앞에 설 수 있다는 것 정도입니다.


다음 글에서는 두 앱의 화면을 하나씩 열어 보면서, 어떤 기능이 어떤 고민에서 나왔는지 소개합니다. 기술 구현이 궁금하시다면 개발기로 바로 가셔도 됩니다.

3rdgeneration family shop
10languages, Italian to Korean
100gordering unit
10minpickup slot interval

A Small Shop by Lake Como

In northern Italy, in a town right by Lake Como, there is a small butcher shop. Macelleria Mazzucchi — run by the same family for three generations.

"A shop next to a tourist spot" might bring souvenir stands to mind, but this place is different. When summer holidays and the Christmas season come around, cars with Swiss, German, French, and British plates pull up in front. Some customers wander in after seeing the lake — but there are also people who cross borders specifically to buy this shop's meat. Regulars, accumulated over three generations.

To me, this isn't a shop I discovered through research. It's my family's shop. So this app didn't start with a brief or a contract. It started at the dinner table.

The Phone and the Notepad

Watch a day at the shop, and you'll see most orders come in by phone. The owner sets down the knife, pulls off a glove, and picks up. Cut and weight are taken down on the notepad next to the register. Glove back on, back to work.

This worked for three generations. But a few scenes kept repeating:

  • At peak hours, hands are full and calls get missed. Nobody knows where that order went.
  • Cut names travel over a phone line, and sometimes the call ends with each side having understood something different.
  • To know the day's revenue, you flip through the receipt pile, one by one.

Above all, phone ordering is a high wall for customers from abroad — you have to explain meat cuts in Italian.

💡 The problem was never technology

The shop didn't need anything as grand as a "digital transformation." It needed to get back the things lost while the phone was ringing — an order, a customer, a quieter evening.

So I Built the Apps

From a single codebase, I built two apps.

In the customer app, you pick a cut, set the weight in 100g steps, and reserve a pickup time in 10-minute slots. Without a phone call, "800g of ribeye, tomorrow at 10:10" arrives exactly as intended.

The owner's app carries the shop's rhythm as-is. How many orders each slot can take, opening hours and the lunch break, Sundays off, manually locking slots on busy days — the shop doesn't adapt to the app; the app adapts to the shop.

There's a butcher-shop detail too. Meat isn't a factory product; an 800g order never cuts to exactly 800g. So the price at order time is an estimate — the final amount is confirmed only when the owner enters the actual measured weight, and the customer pays that amount at pickup. It's the neighborhood butcher's age-old way of doing business, translated into code.

When a new order arrives, the owner's phone buzzes. When an order is ready, the customer's phone buzzes. Instead of missed calls — notifications that don't miss.

A Butcher Shop That Speaks Ten Languages

Open the language list in the customer app and ten options appear: Italian, English, German, French, Spanish, Dutch, Portuguese, Japanese, Chinese, and Korean. That sounds excessive for a neighborhood butcher — until you look at the customer roster. These are the people crossing the lake from Switzerland, Germany, France, and the UK.

Switching languages changes more than button labels. Cut names and descriptions live in translation tables, so the same display counter reads Entrecôte de bœuf to a French customer and Rinder-Ribeye to a German one. Even the shop name shifts — Boucherie, then Metzgerei.

French menu screen — Boucherie Mazzucchi
What a French customer sees — Boucherie Mazzucchi, Entrecôte de bœuf
German menu screen — Metzgerei Mazzucchi
What a German customer sees — Metzgerei Mazzucchi, Rinder-Ribeye

And Korean? An honest confession: I added it for my own convenience as the developer. When a Korean developer builds an app for an Italian butcher shop, testing in your mother tongue is a small comfort. As a result, this is probably the only butcher shop by Lake Como with Korean language support.

✅ Adding a language is data, not code

Product and category names were designed from day one as translation tables (product_translations) rather than hardcoded strings — so adding a language is a data change, not a code change. Products without a translation yet quietly fall back to Italian; the menu never breaks.

Bringing Technology into a Third-Generation Shop

The most delicate part of this project wasn't technical. It was making sure the shop's way of working stayed intact.

A three-generation shop already has a finished rhythm: open in the morning, rest at lunch, close on Sundays, remember what the regulars like. The app's job was to support that rhythm, not rewrite it. That's why the admin settings screen speaks the shop owner's language: "opening hours," "lunch break," "closing days," "slot lock."

The phone still rings. The old regulars still order by phone, and that's fine. But now there's an app sitting next to the notepad — and customers from across the border, or customers whose Italian is shaky, can stand at the same counter.


In the next post, I'll open up both apps screen by screen and show which features came from which concerns. If you're curious about the technical side, see the dev log.

관람해 주셔서 고맙습니다

© 2026 나리인포메이션(Nari Information). All rights reserved.

사업자등록번호 746-08-03415 · hello@nariinfo.dev

LevelUp PianoMazzucchiVault