← 기술 블로그 목록으로 돌아가기
#940 • Schedule Governance & 42-Cell Matrix Calendar Architecture

공교육 학사 일정과 국방 훈련 계획의 0초 시각화: ZeliCal의 42셀 동적 매트릭스 그리드와 온디바이스 캘린더 거버넌스 아키텍처

"교원의 공문 마감일과 군 훈련 계획이 외산 클라우드 캘린더의 해외 서버로 무단 동기화되거나, 인터넷이 끊긴 폐쇄망에서 일정이 백지화되는 참사를 어떻게 방어하십니까?" 빅테크 계정 로그인과 유료 구독을 요구하는 상용 캘린더를 종식하는 Zero-Telemetry 온디바이스 캘린더 런타임, 42셀(6주 × 7일) 가변 월력 동적 매트릭스 알고리즘을 통한 이전/다음 달 경계 날짜의 투명도 자동 계층화, CalendarService 기반의 로컬 샌드박스(%LocalAppData%\ZeliDesk\Calendar\schedules.json) 완전 격리 영속화, Cell_Tapped 원터치 ContentDialog 일정 등록/수정/삭제 모달, 텍스트 자동 말줄임(CharacterEllipsis) 칩 렌더링, 그리고 WindowKit Always-On-Top 플로팅 아키텍처 백서.

"초·중·고 교무실의 학사 일정에는 중간·기말고사 출제 기간, 전국연합학력평가 시험일, 학교운영위원회 일정, 교원 인사 이동 등 대외비 성격의 민감한 날짜가 다수 포함되어 있습니다. 군부대 사령부와 국방 연구소 역시 전술 훈련 D-Day와 보안 감사 일정을 관리해야 합니다. 그러나 많은 구성원들이 편리하다는 이유로 구글 캘린더나 마이크로소프트 아웃룩에 이 일정을 기록합니다. 그 순간 민감한 행정 일정이 국외 서버로 전송되며, 정작 망분리 PC나 시험 출제 합숙장에서는 인터넷 차단으로 캘린더를 열어볼 수도 없습니다. ZeliCal은 외부 통신 0바이트의 완전한 온디바이스 환경에서 가장 직관적인 42셀 매트릭스로 학사 일정을 투명하게 통제합니다."

1. 공교육 교무실과 군 연구실의 일정 관리 딜레마: "빅테크 클라우드 동기화와 폐쇄망 고립의 갈림길"

현대 공공 교육과 국방 행정 현장에서 일정 관리 소프트웨어는 필수적이지만, 다음과 같은 보안 및 운영상 장벽이 상존합니다:

2. 상용 클라우드 캘린더(Google/Outlook)의 구조적 한계: "계정 강제, 로컬 오프라인 부재, 데이터 유출 위험"

빅테크가 제공하는 범용 캘린더 서비스들은 다음과 같은 구조적 제약을 지닙니다:

  1. 개인 구글/MS 계정 로그인 강제: 공용 PC나 전산실 단말기에서 개인 계정으로 로그인해야 하므로 자동 로그인으로 인한 타인의 계정 무단 도용 위험이 매우 큽니다.
  2. 과도한 웹 런타임 메모리 소모: 브라우저 탭 하나를 띄워두는 것만으로 200MB 이상의 메모리를 점유하여 저사양 행정용 PC의 속도를 저하시킵니다.
  3. 서버 장애 시 업무 마비: 2024년 글로벌 클라우드 서비스 중단 사태처럼 외부 데이터센터에 장애가 발생하면 즉시 전산실 전체의 일정 조회가 마비됩니다.
flowchart TD subgraph UI_MATRIX["🖥️ WinUI 3 42셀 동적 매트릭스 그리드"] HEADER["년/월 헤더 (MonthYearText) & 이전/다음/오늘 버튼"] GRID["6주 × 7일 (42개 Border 셀) 반응형 뷰"] CHIP["일정 칩 (TextTrimming 말줄임 배지)"] HOVER["포인터 인터랙션 (호버 밝기 / 오늘 날짜 하이라이트)"] end subgraph ENGINE_CORE["⚙️ ZeliCal 월력 수학 & 상태 엔진"] FIRST["월초 기준일 연산 (DateTime(y, m, 1))"] OFFSET["요일 오프셋 역산 (startDate = firstDay - DayOfWeek)"] LOOP["42일 연속 순회 (AddDays(i))"] OPACITY["당월(Opacity 1.0) vs 전후월(Opacity 0.3) 자동 분류"] end subgraph STORAGE_LAYER["💾 CalendarService 로컬 영속화"] CACHE["인메모리 캐시 (List<CalendarItem>)"] JSON["LocalFolder / schedules.json (Indented 직렬화)"] ZERO["🚫 네트워크 소켓 0바이트 (Air-Gapped Local)"] end HEADER --> FIRST --> OFFSET --> LOOP LOOP --> OPACITY --> GRID GRID --> HOVER & CHIP CHIP -->|Cell_Tapped| CACHE CACHE --> JSON --> ZERO
▲ [그림 1] ZeliDesk ZeliCal의 42셀 동적 매트릭스 알고리즘 및 CalendarService 로컬 영속화 파이프라인

3. 42셀(6주 × 7일) 가변 월력 동적 매트릭스 렌더링 알고리즘

달력의 시작 요일은 매달 달라지며, 한 달이 5주로 끝나는 경우도 있고 6주에 걸치는 경우도 있습니다. ZeliCal은 UI 그리드의 크기가 덜컹거리며 변하는 현상을 원천 방지하기 위해 고정형 42셀(6 × 7) 매트릭스 구조를 채택하였습니다.

해당 월의 1일이 시작하는 요일(DayOfWeek)을 구한 뒤, 음수 오프셋(-startDayOfWeek)을 더해 첫 번째 일요일 날짜(startDate)를 산출하고 42회 연속 루프를 수행합니다:

C# (RenderCalendar 매트릭스 계산 알고리즘) ZeliCal/Views/ZeliCalWindow.xaml.cs
private void RenderCalendar()
{
    MonthYearText.Text = string.Format(Loc.Get("Cal_MonthYear"), _currentDate.Year, _currentDate.Month);

    // 1. 당월 1일의 요일 오프셋 계산 (0 = 일요일, 6 = 토요일)
    var firstDayOfMonth = new DateTime(_currentDate.Year, _currentDate.Month, 1);
    int startDayOfWeek = (int)firstDayOfMonth.DayOfWeek;

    // 2. 캘린더 첫 번째 칸에 표시될 시작 날짜 산출 (이전 달의 마지막 일요일)
    var startDate = firstDayOfMonth.AddDays(-startDayOfWeek);

    // 3. 당월 등록된 전체 일정 로컬 캐시에서 조회
    var schedules = CalendarService.GetItemsForMonth(_currentDate.Year, _currentDate.Month);

    // 4. 42개 셀(6주 x 7일) 순차 렌더링
    for (int i = 0; i < 42; i++)
    {
        var currentDate = startDate.AddDays(i);
        var cell = _cells[i];
        _cellDates[cell] = currentDate;

        bool isCurrentMonth = currentDate.Month == _currentDate.Month;
        bool isToday = currentDate.Date == DateTime.Now.Date;
        bool isSunday = currentDate.DayOfWeek == DayOfWeek.Sunday;
        bool isSaturday = currentDate.DayOfWeek == DayOfWeek.Saturday;

        // 오늘 날짜 젤리 그린(#300EA76C) 하이라이트
        cell.Background = isToday
            ? new SolidColorBrush(Color.FromArgb(0x30, 0x0E, 0xA7, 0x6C))
            : new SolidColorBrush(Color.FromArgb(0x10, 0xFF, 0xFF, 0xFF));

        // 날짜 텍스트 투명도 자동 계층화 (당월 1.0 vs 전달/다음달 0.3)
        var dateText = new TextBlock
        {
            Text = currentDate.Day.ToString(),
            FontSize = 14,
            FontWeight = FontWeights.SemiBold,
            Opacity = isCurrentMonth ? 1.0 : 0.3
        };

        if (isSunday) dateText.Foreground = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0x55, 0x55));
        if (isSaturday) dateText.Foreground = new SolidColorBrush(Color.FromArgb(0xFF, 0x55, 0xAA, 0xFF));
        
        // ... 날짜별 일정 칩(Chip) 바인딩
    }
}

이 알고리즘을 통해 전월과 차월의 경계 날짜들이 자연스러운 투명도(Opacity 0.3)로 블러링되어, 사용자는 월을 넘나드는 연휴나 시험 기간을 단 0.1초 만에 인지할 수 있습니다.

4. CalendarService 로컬 샌드박스 영속화 파이프라인 (인메모리 캐시 & Indented JSON)

ZeliCal의 데이터 관리를 담당하는 CalendarService는 윈도우 OS의 표준 로컬 데이터 저장소인 %LocalAppData%\ZeliDesk\Calendar\schedules.json을 사용합니다.

자주 발생하는 월 전환 및 조회 작업에서 디스크 I/O 병목을 제거하기 위해 인메모리 정적 캐시(Static Cache)를 유지하며, 수정이 발생할 때만 읽기 쉬운 포맷(Indented JSON)으로 디스크에 커밋합니다:

C# (CalendarService 영속화 엔진) Core/Services/CalendarService.cs
public static class CalendarService
{
    private static readonly string _filePath = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
        "ZeliDesk", "Calendar", "schedules.json");

    private static List<CalendarItem> _cache = null;

    public static List<CalendarItem> LoadAll()
    {
        if (_cache != null) return _cache; // 메모리 캐시 즉각 반환 (0ms)
        if (!File.Exists(_filePath)) return _cache = new List<CalendarItem>();

        try
        {
            var json = File.ReadAllText(_filePath);
            _cache = JsonSerializer.Deserialize<List<CalendarItem>>(json) ?? new();
        }
        catch { _cache = new(); }
        return _cache;
    }

    public static void SaveAll(List<CalendarItem> items)
    {
        _cache = items;
        try
        {
            var json = JsonSerializer.Serialize(_cache, new JsonSerializerOptions { WriteIndented = true });
            File.WriteAllText(_filePath, json);
        }
        catch { }
    }

    public static List<CalendarItem> GetItemsForMonth(int year, int month)
    {
        return LoadAll().Where(x => x.Date.Year == year && x.Date.Month == month).ToList();
    }
}

5. Cell_Tapped 대화형 모달(ContentDialog)과 원터치 일정 CRUD 거버넌스

기존 캘린더 프로그램들은 일정을 하나 등록하려면 별도의 거대한 입력 폼 창이 열리거나 새 탭으로 이동해야 했습니다.

ZeliCal은 사용자가 특정 날짜의 셀을 가볍게 클릭(Tapped)하는 순간, WinUI 3 ContentDialog 인플레이스 모달을 띄워 제목과 메모를 즉시 작성·수정·삭제할 수 있는 원터치 CRUD 환경을 제공합니다:

sequenceDiagram autonumber actor Teacher as 교원 / 행정관 participant Cell as 캘린더 날짜 셀 (Border) participant Modal as ContentDialog 모달 participant Service as CalendarService (Cache) participant Disk as LocalStorage (schedules.json) Teacher->>Cell: 10월 15일 셀 클릭 (Cell_Tapped) Cell->>Modal: ContentDialog 팝업 (기존 일정 제목·메모 로드) Teacher->>Modal: "중간고사 출제 마감" 입력 후 [저장] 클릭 Modal->>Service: AddOrUpdateItem(item) 호출 Service->>Service: _cache 내 신규 항목 추가/교체 Service->>Disk: File.WriteAllText (JSON 커밋) Service->>Cell: RenderCalendar() 재호출 ➔ 녹색 일정 칩 즉각 표시 Note over Teacher,Cell: 클릭부터 일정 저장까지 단 2초 만에 완결!
▲ [그림 2] 캘린더 셀 탭 기반의 원터치 인플레이스 일정 등록/수정/삭제 시퀀스

6. TextTrimming 말줄임 칩 렌더링 및 휴일·주말(토/일) 고대비 시각화

교무 일정은 "1학기 방과후학교 수강신청 안내문 발송 및 행정실 정산 보고"처럼 제목이 긴 경우가 많습니다. 셀 크기를 벗어나는 긴 텍스트가 줄바꿈되어 캘린더 그리드가 세로로 깨지는 문제를 방지하기 위해, ZeliCal은 하드웨어 가속 말줄임표(CharacterEllipsis) 칩 렌더링을 적용하였습니다:

7. 캘린더 솔루션 비교 분석 (Google Calendar vs Outlook vs 종이 달력 vs ZeliCal)

비교 항목 구글 캘린더 (Google Calendar) MS 아웃룩 (Outlook Calendar) 탁상용 종이 달력 ZeliDesk ZeliCal 온디바이스
데이터 저장 위치 구글 클라우드 해외 서버 MS 클라우드 해외 서버 오프라인 실물 완전 격리 로컬 OS 샌드박스 (JSON)
폐쇄망 / Air-Gap 구동 불가 (인터넷 필수) 오프라인 제한적 (계정 동기화 필요) 완벽 구동 100% 오프라인 Zero-Telemetry
계정 로그인 요구 Google 계정 필수 Microsoft 계정 필수 없음 로그인 0회 / Zero-Config
그리드 레이아웃 구조 동적 반응형 (주/월 변환) 고정 데스크톱 뷰 고정 인쇄면 42셀 동적 매트릭스 고정 그리드
메모리 점유율 (RAM) 250MB ~ 500MB (웹 탭) 300MB ~ 800MB 0MB 초경량 15MB 이하 (WinUI 3)
Always-On-Top 플로팅 불가 (창 뒤로 숨음) 불가 책상 위 상시 비치 WindowKit 하드웨어 가속 원터치 핀

8. 결론: "외부 서버 연결 0바이트, 신뢰할 수 있는 공교육·국방 온디바이스 학사 거버넌스"

학사 일정과 군사 훈련 계획은 단순한 날짜의 나열이 아니라, 한 학기와 한 해의 조직 운영을 이끄는 핵심 나침반입니다. 이러한 중요한 정보를 다루는 도구가 클라우드 접속 장애나 계정 관리 실수로 흔들려서는 안 됩니다.

ZeliDesk의 ZeliCal은 복잡한 설치나 회원가입 절차 없이, 단 0초 만에 42셀의 미려한 매트릭스를 펼쳐 교원과 연구원의 일정을 완벽하게 보호합니다. 가장 순수하고 독립적인 온디바이스 기술로 완성된 ZeliCal과 함께, 대한민국의 스마트 교실과 국방 교육 현장은 흔들림 없는 시간과 일정의 주권을 확립하게 되었습니다.

← 이전 기술 백서 #941 디지털교과서(AIDT) 수업 몰입과 수능·임용 실전 시뮬레이션: ZeliTimer의 100ms 델타 보정 타이머와 뽀모도로 세션 거버넌스 아키텍처 다음 기술 백서 → #939 공교육 다문화 수업과 국방 다국적 연합작전의 0초 시차 동기화: ZeliClock의 TimeZoneInfo 기반 글로벌 멀티 타임존 실시간 렌더링과 스레드 안전 파일 영속화 아키텍처
📅 ZeliDesk ZeliCal 온디바이스 캘린더 런타임 체험하기
Google 캘린더 없이 0초 만에 학사 일정을 확인하고, 완전한 오프라인 일정 거버넌스를 경험하세요.
72종 유틸리티 전체 둘러보기 →