2025.02.03 (์›”)

โœจ GPT์˜ ์š”์•ฝ ใ€€

FleatherViewer์˜ ์—…๋ฐ์ดํŠธ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ , HomeFeedPage์˜ ํ•„ํ„ฐ๋ง ๋ฐฉ์‹ ๊ฐœ์„ ์„ ํ†ตํ•ด ์ด์Šˆ ํ•ด๊ฒฐ ๋ฐ ์„ฑ๋Šฅ ์ตœ์ ํ™” ์™„๋ฃŒ. ๋•๋ถ„์— Query ํ•„ํ„ฐ ๋Œ€์‹  Conditional Visibility๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ํšจ๊ณผ์ ์ž„์„ ๋ฐฐ์› ์Œ.

๐Ÿ’ป ๊ฐœ๋ฐœ ์ผ์ง€

โฐ ์˜ค๋Š˜ ํ•  ์ผ

  • โœ… (์ด์Šˆ) HomeFeedPage - FeedCardDiary: ListView์—์„œ ๋‚ ์งœ๋ฅผ ๋ณ€๊ฒฝํ•ด๋„, ์˜ค์ง FleatherViewerWidget๋งŒ ๊ฐ’์ด ๋ณ€ํ•˜์ง€ ์•Š์Œ.
    • ์•„๋งˆ Widget์˜ initialDeltaJson ๊ฐ’์ด Diary Document ๋ณ€๊ฒฝ ์‹œ๋งˆ๋‹ค ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Œ.
    • o1์—๊ฒŒ ๋ฌผ์–ด๋ณด์ž๋งˆ์ž ํ•œ ๋ฐฉ์— ํ•ด๊ฒฐ.

      /// didUpdateWidget:
      ///  - ๋™์ผ ์œ„์ ฏ ํŠธ๋ฆฌ์—์„œ ๋‹จ์ˆœํžˆ ํŒŒ๋ผ๋ฏธํ„ฐ๋งŒ ๋ฐ”๋€ ๊ฒฝ์šฐ, Flutter๊ฐ€ ๊ธฐ์กด State๋ฅผ ์žฌ์‚ฌ์šฉ.
      ///  - ์ด๋•Œ ์ƒˆ widget ์†์„ฑ๊ณผ ๊ธฐ์กด widget ์†์„ฑ์„ ๋น„๊ตํ•˜์—ฌ ํ•„์š”ํ•œ ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Œ.
      @override
      void didUpdateWidget(covariant FleatherViewerWidget oldWidget) {
        super.didUpdateWidget(oldWidget);
      
        // 1) ์ด์ „ JSON๊ณผ ์ƒˆ๋กœ์šด JSON์ด ๋‹ค๋ฅด๋ฉด
        if (oldWidget.initialDeltaJson != widget.initialDeltaJson) {
          // 2) FleatherController๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑ
          _controller?.dispose();
          _controller = _createControllerFromDeltaJson(widget.initialDeltaJson);
          // 3) UI ๊ฐฑ์‹ 
          setState(() {});
        }
      }
      
      /// Delta JSON ๋ฌธ์ž์—ด์„ FleatherController๋กœ ๋งŒ๋“œ๋Š” ํ—ฌํผ ํ•จ์ˆ˜
      FleatherController _createControllerFromDeltaJson(String jsonString) {
        ParchmentDocument doc;
        try {
          final decoded = jsonDecode(jsonString);
          doc = ParchmentDocument.fromJson(decoded);
        } catch (e) {
          // ๋ณต์› ์‹คํŒจ ์‹œ, ์ผ๋ฐ˜ ํ…์ŠคํŠธ ์ฒ˜๋ฆฌ
          doc = ParchmentDocument.fromDelta(
            Delta()..insert(_ensureEndsWithNewline(jsonString)),
          );
        }
        return FleatherController(document: doc);
      }
      
  • โœ… (์ด์Šˆ) HomeFeedPage: On page load์‹œ Unexpected Null Value ์ž ๊น ๋–ด๋‹ค ์‚ฌ๋ผ์ง.
    • HomeFeedPage์˜ Listview์— ๊ฑธ๋ฆฐ ๋‚ ์งœ ํ•„ํ„ฐ๋ง์ด ๋ฌธ์ œ์ธ ๊ฒƒ์œผ๋กœ ํ™•์ธ.
    • โ€˜ListViewโ€™์˜ โ€˜Backend Queryโ€™ ์˜ต์…˜์—์„œ Filter On Null Values๋ฅผ ์ผœ๋ดค์Œ.
      • Filter On Null Values: By default, if the value of any filter is null, the query will ignore the filter for that field. Checking this will instead keep null filters.
    • Backend Query - Query Collection ์ˆ˜์ • ์‹œ๋„ 1 (์‹คํŒจ)
      • Filter On Null Values: ON
      • Filter 1: created_time, Equal To, getFirstTimeOfTheDay
      • Filter 2: created_time, Less Than, getFirstTimeOfNextDay
      • Order by: created_time, Decreasing
      • Backend Query ์„ค์ • ์™„๋ฃŒ ๋ถˆ๊ฐ€
        • ์—๋Ÿฌ ๋ฉ”์‹œ์ง€: You canโ€™t order your query by a field used in a filter using == or in.
    • Backend Query - Query Collection ์ˆ˜์ • ์‹œ๋„ 2 (์‹คํŒจ)
      • Filter On Null Values: ON
      • Filter 1: created_time, Greater Than or Equal To, getFirstTimeOfTheDay
      • Filter 2: created_time, Less Than, getFirstTimeOfNextDay
      • Order by: created_time, Decreasing
      • Backend Query ์„ค์ • ์™„๋ฃŒ ๊ฐ€๋Šฅ
      • ๋””๋ฒ„๊น… ๋ชจ๋“œ ์ง„์ž… ์‹œ ์•„๋ž˜์˜ ์—๋Ÿฌ๊ฐ€ ๋œจ๊ณ  ํŽ˜์ด์ง€๊ฐ€ ์ƒ์„ฑ ์•ˆ ๋จ.

        Assertion failed: file:/// opt/ - pub-cache/hosted/pub.dev/ cloud_firestore-5.5.0/lib/src/ query dart: 650:9
              
        conditions
        .where ((List<dynamic> item) => equality.equals(condition, item))
          .isEmpty
        "Condition [FieldPath([created_time]), !=, null] already exists in this query."
              
        The relevant error-causing widget was: HomeFeedWidget
        
    • Backend Query - Query Collection ์ˆ˜์ • ์‹œ๋„ 3 (์‹คํŒจ)
      • Filter On Null Values: ON
      • Filter 1: created_time, Greater Than, getLastTimeOfPrevDay
      • Filter 2: created_time, Less Than, getFirstTimeOfNextDay
      • Order by: created_time, Decreasing
      • Backend Query ์„ค์ • ์™„๋ฃŒ ๊ฐ€๋Šฅ
      • ๋””๋ฒ„๊น… ๋ชจ๋“œ ์ง„์ž… ์‹œ ์•„๋ž˜์˜ ์—๋Ÿฌ๊ฐ€ ๋œจ๊ณ  ํŽ˜์ด์ง€๊ฐ€ ์ƒ์„ฑ ์•ˆ ๋จ.

        Assertion failed: file:/// opt/ - pub-cache/hosted/pub.dev/ cloud_firestore-5.5.0/lib/src/ query dart: 650:9
              
        conditions
        .where ((List<dynamic> item) => equality.equals(condition, item))
          .isEmpty
        "Condition [FieldPath([created_time]), !=, null] already exists in this query."
              
        The relevant error-causing widget was: HomeFeedWidget
        
    • Backend Query - Query Collection ์ˆ˜์ • ์‹œ๋„ 4 (์‹คํŒจ)
      • Filter On Null Values: OFF
      • Filter 1: created_time, Greater Than, getLastTimeOfPrevDay
      • Filter 2: created_time, Less Than, getFirstTimeOfNextDay
      • Order by: created_time, Decreasing
      • Backend Query ์„ค์ • ์™„๋ฃŒ ๊ฐ€๋Šฅ
      • ๋””๋ฒ„๊น… ๋ชจ๋“œ ์ง„์ž… ์‹œ ์•„๋ž˜์˜ ์—๋Ÿฌ๊ฐ€ ์ž ๊น ๋–ด๋‹ค ์‚ฌ๋ผ์ง.

        Unexpected Null value.
        
        The relevant error-causing widget was: HomeFeedWidget
        
    • (o1 ์—๊ฒŒ ์งˆ๋ฌธ) ์™œ Unexpected Null Value๊ฐ€ ์ž ๊น ๋œจ๋Š” ๊ฑธ๊นŒ?
      • FlutterFlow(ํ˜น์€ ๋‚ด๋ถ€ ์ฝ”๋“œ)์—์„œ ํŽ˜์ด์ง€ ์ดˆ๊ธฐ ๋กœ๋”ฉ ์‹œ์ ์— getLastTimeOfPrevDay()๋‚˜ getFirstTimeOfNextDay() ๋“ฑ์ด null์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ์ปค. (์˜ˆ: date๊ฐ€ ์•„์ง ์ดˆ๊ธฐํ™”๊ฐ€ ์•ˆ ๋๋‹ค๋“ ์ง€โ€ฆ)
      • Filter On Null Values๊ฐ€ ์ผœ์ ธ ์žˆ์œผ๋ฉด, ๋‚ด๋ถ€์ ์œผ๋กœ != null ๊ฐ™์€ ์กฐ๊ฑด์„ ๋”ฐ๋กœ ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๊ฒŒ ๋กœ๋”ฉ ์ˆœ๊ฐ„์— null ๊ฐ’์ด ๋“ค์–ด๊ฐ€๋ฉด์„œ ์ถฉ๋Œ์ด ๋‚  ์ˆ˜ ์žˆ์–ด.
      • ๊ทธ๋ž˜์„œ โ€œ์ž ๊น null ์—๋Ÿฌ ๋„์šฐ๊ณ  -> ์‹ค์ œ ๊ฐ’์œผ๋กœ ๋Œ€์ฒด๋œ ๋’ค -> ๋กœ๋”ฉ์ด ๋๋‚˜๋ฉด ์‚ฌ๋ผ์ง€๋Š”โ€ ํ˜„์ƒ์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฑฐ์ง€.
    • Backend Query - Query Collection ์ˆ˜์ • ์‹œ๋„ 5 (์„ฑ๊ณต!)
      • Filter On Null Values: OFF
      • Order by: created_time, Decreasing
      • Component Widget Conditional Visibility ์„ค์ •
        • Filter 1: created_time, Greater Than, getLastTimeOfPrevDay
        • Filter 2: created_time, Less Than, getFirstTimeOfNextDay
      • ๊ฒŒ๋‹ค๊ฐ€ ๋ค์œผ๋กœ, ListView ๋กœ๋”ฉ ๋ ‰(Latency)์ด ์‚ฌ๋ผ์กŒ์Œ. Query์— Filter 2๊ฐœ์™€ Order๋ฅผ ๋™์‹œ์— ์คฌ๊ธฐ์— ๋งŽ์€ ์‹œ๊ฐ„์ด ์†Œ์š”๋œ ๊ฒƒ ๊ฐ™์Œ.
    • ๐Ÿ’ก ๋ฐฐ์šด ์ 
      • Backend Query ์‚ฌ์šฉํ•  ๋•Œ๋Š” ํ•„ํ„ฐ ์‚ฌ์šฉ์„ ์ตœ๋Œ€ํ•œ ๋ฐฐ์ œํ•˜๊ณ , Conditional Visibility๋กœ ์ปจํŠธ๋กค ํ•˜๋Š” ๊ฒŒ ์ข‹๋‹ค.
      • ์ด๊ฑฐ ์ดˆ๋ฐ˜์— ๋ฉ˜ํ† ๋‹˜๊ป˜ ์—ฌ์ญค๋ด์„œ ๋‹ต๋ณ€ ๋ฐ›์•˜๋˜ ๊ฑด์ธ๋ฐ, ๋จธ๋ฆฌ๋กœ๋งŒ ๋Œ€์ถฉ ์ดํ•ดํ•˜๊ณ  ๋„˜์–ด๊ฐ€์„œ ๊ฒฐ๊ตญ ์žŠ์–ด๋ฒ„๋ ธ๋˜ ๊ฒƒ ๊ฐ™๋‹ค. ์ง์ ‘ ๊ณ ์ƒํ•ด๋ณด๊ณ ๋‚˜๋‹ˆ๊นŒ ์ด์ œ์„œ์•ผ ํ™•์‹คํžˆ ๊นจ๋‹ซ๊ฒŒ ๋˜์—ˆ์Œ.
  • โœ… (์ด์Šˆ) DiaryPage: ๋‚ ์งœ๊ฐ€ ์˜ค๋Š˜๋กœ๋งŒ ์ €์žฅ๋จ
    • DiaryPage - dateFocused ํŒŒ๋ผ๋ฏธํ„ฐ ์ƒ์„ฑ
    • HomeFeedPage์˜ dateToShow๊ฐ’์„ dateFocused ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ.

๐Ÿ’ฏ ํ•œ ์ผ์— ๋Œ€ํ•œ ์š”์•ฝ

FleatherViewer ์—…๋ฐ์ดํŠธ ๋ฌธ์ œ ํ•ด๊ฒฐ

  • didUpdateWidget์„ ํ™œ์šฉํ•ด FleatherViewer๊ฐ€ Diary Document ๋ณ€๊ฒฝ ์‹œ๋งˆ๋‹ค ์ •์ƒ์ ์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜๋„๋ก ์ˆ˜์ •. HomeFeedPage ํ•„ํ„ฐ ์ตœ์ ํ™”

Backend Query์˜ ํ•„ํ„ฐ๋ง ๋ฐฉ์‹ ๋Œ€์‹  Conditional Visibility๋ฅผ ํ™œ์šฉํ•ด ์„ฑ๋Šฅ ๊ฐœ์„ .

  • Query ํ•„ํ„ฐ๋ง์„ ์ตœ์†Œํ™”ํ•จ์œผ๋กœ์จ ๋กœ๋”ฉ ์†๋„ ํ–ฅ์ƒ.

DiaryPage ๋‚ ์งœ ์ €์žฅ ์˜ค๋ฅ˜ ์ˆ˜์ •

  • HomeFeedPage์—์„œ DiaryPage๋กœ dateFocused ๊ฐ’์„ ์ „๋‹ฌํ•˜์—ฌ, ์ƒˆ๋กœ์šด ์ผ๊ธฐ๊ฐ€ ์ž‘์„ฑ๋  ๋•Œ ์„ ํƒ๋œ ๋‚ ์งœ๊ฐ€ ๋ฐ˜์˜๋˜๋„๋ก ๊ฐœ์„ .

๐ŸŽฏ ์ถ”ํ›„์— ํ•  ์ผ

์ž์„ธํžˆ ๋ณด๋ ค๋ฉด ํด๋ฆญ
  • โ” (์ด์Šˆ) DiaryPage: ๋งˆํฌ๋‹ค์šด ๋ทฐ์–ด ํ™œ์šฉ (์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐฉ์ง€: Container Height)
  • โ” (์ด์Šˆ) HomeFeedPage - FeedCardDiary: AI Comment ์บ๋ฆญํ„ฐ ์ด๋ฏธ์ง€ ์•Œ๋งž๊ฒŒ ์ ์šฉ
    • โ” DiaryPage - AI Comment: Save์‹œ, ์ฝ”๋ฉ˜ํŠธ ์ž‘์„ฑํ•œ ์บ๋ฆญํ„ฐ Ref๋„ Diary์— ์ €์žฅ.
    • โ” HomeFeedPage - FeedCardDiary - AI Image: Backend Query๋กœ ์บ๋ฆญํ„ฐ Doc ๋ถˆ๋Ÿฌ์™€์„œ Image Path ์ง€์ •.
  • โ” DiaryPage: Mood Slider ๊ฐ’์— ๋”ฐ๋ผ ์–ผ๊ตด ํ‘œ์ • Emoji ๋ณ€๊ฒฝ

  • โ” Chat Page - Create New Chat: ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ ์ ์šฉํ•˜๊ธฐ
    • โ–ถ๏ธ OpenAI API Call ๊ตฌํ˜„: createChatCompletion
      • Input: System Prompt(Chat)
      • Output: New Chat Message by AI($.choices[0].message.content)
      • Additional Actions: Create New Chat, Create New Message
  • โ” DiaryPage - Create New Chat by Diary: ์ผ๊ธฐ์˜ ๋‚ด์šฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ, New Chat ์ƒ์„ฑ
    • โ” OpenAI API Call ๊ตฌํ˜„: createDiaryComment
      • Input: Diary Content, System Prompt(AI Comment)
      • Output: AI Comment($.choices[0].message.content)
    • โ” OpenAI API Call ๊ตฌํ˜„: createDiarySummary
      • Input: Diary Content, AI Comment, System Prompt(Diary Summary)
      • Output: Diary Summary($.choices[0].message.content)
    • โ” OpenAI API Call ๊ตฌํ˜„: createChatFromDiary
      • Input: Diary Summary, System Prompt(Chat From Diary)
      • Output: New Chat Message by AI($.choices[0].message.content)
      • Additional Actions: Create New Chat, Create New Message
  • โ” ChatPage - Create New Diary: ๋Œ€ํ™” ๋‚ด์šฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ, New Diary ์ƒ์„ฑ
    • โ” OpenAI API Call ๊ตฌํ˜„: createChatSummary
      • Input: Chat Content, System Prompt(Diary From Chat)
      • Output: Chat Summary
  • โ” ChatPage - Create New Diary: ๋Œ€ํ™” ๋‚ด์šฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ, New Diary ์ƒ์„ฑ
    • โ” OpenAI API Call ๊ตฌํ˜„: createDiaryFromChat
      • Input: Chat Summary, System Prompt(Diary From Chat)
      • Output: New Diary(Title, Content, Mood score)
  • โ” ChatPage: Go to Linked Diary

  • โ” HomeFeedPage - flutter_slidable:4.0.0 import ํ›„ ์ ์šฉํ•˜๊ธฐ
  • โ” HomeFeedPage: FeedCardDiary์—์„œ ์ขŒ์šฐ slide์‹œ ์ฑ„ํŒ…/ํŽธ์ง‘/์‚ญ์ œ

  • โ” ChatPage: ์œ ์ € ๋Œ€ํ™” ์ถœ๋ ฅ ๋‚ด์šฉ์€ ์˜ค๋ฅธ์ชฝ ์ •๋ ฌ
  • โ” Chat/Diary: GPT Streaming API

  • โ” ChatPage - AI ์„ ํ†ก ๊ตฌํ˜„ (Alarm/Notification)
    • ์ฑ„ํŒ… ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ์˜ ํ•ต์‹ฌ์€ ๋Šฅ๋™ํ˜•์ด๋‹ค.
      • ๋” ๋ฆฌ์–ผํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด, create_date of diary/chat ๋„ ์ „๋‹ฌํ•ด์„œ, โ€˜์–ด์ œโ€™ ๋“ฑ ๋‚ ์งœ๋ฅผ ์–ธ๊ธ‰ํ•˜๋ฉด ์ข‹์„ ๋“ฏ.
    • Alarm ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ์ฐธ์กฐ
  • โ” DiaryPage: ์„ธ๋ถ€ ๊ฐ์ • ํ‚ค์›Œ๋“œ Choice Chips ์ถ”๊ฐ€ ํ›„ DB ์—ฐ๋™ ์„ค์ •
  • โ” DiaryPage - AI Comment: Choice chips, mood slider ๋“ฑ์˜ ์ž…๋ ฅ๊ฐ’๋“ค์„ AI Comment System Prompt์— ์•Œ๋งž๊ฒŒ ๋ณ€๊ฒฝ.
    • โ” **์ด์ „ ์ผ๊ธฐ ๋˜๋Š” ๋Œ€ํ™” ๋‚ด์—ญ ์ „์ฒด (๋•œ๋นต ๊ธฐ์ˆ ๋ถ€์ฑ„)
    • โ” ์‚ฌ์šฉ์ž ๊ธฐ๋ณธ ์ •๋ณด: ์ด๋ฆ„, ์„ฑ๋ณ„, MBTI, โ€ฆ
    • โ” ์„ธ๋ถ€ ๊ฐ์ • ํ‚ค์›Œ๋“œ: ์ฆ๊ฑฐ์šด, ์Šฌํ”ˆ, โ€ฆ
    • โ” ์บ๋ฆญํ„ฐ ์„ค์ •: ์†Œ๋ฏธ, ์„ธ๋‚˜, ๋ฏผํ˜
    • โ” ๊ฐ์ • ์ˆ˜์น˜: 1~100์ 
    • โ” ๋‹ต๋ณ€ ์–‘์‹: ์น˜์œ ํ˜•(Healing), ์กฐ์–ธํ˜•(Suggestion), ์ •๋ณดํ˜•(Informative)
    • โ” ๋‹ต๋ณ€ ๊ธธ์ด: ์งง๊ฒŒ, ๋ณดํ†ต, ์ž์„ธํžˆ
    • is New Chat
      • ํ•ด๋‹น Chat์˜ messages๋Š” ์ฒ˜์Œ ์ƒ์„ฑํ•˜๋Š” ๊ฑฐ๋‹ˆ๊นŒ, ์ฒซ ์ƒ์„ฑํ•˜๋Š” message document์˜ is_initial = true๊ฐ’ ์ค˜๋ฒ„๋ฆฌ๊ณ  ๋ชจ๋“  ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ ๋‹ค ๋•Œ๋ ค๋„ฃ์Œ.
        • is_initial = false
        • ํ•œ๊ณ„์ : ๋งจ ์ฒ˜์Œ message document์—๋‹ค๊ฐ€ ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ ๋•Œ๋ ค๋„ฃ์œผ๋ฉด, ๋Œ€ํ™” ๋„์ค‘ ์ˆ˜์ • ํž˜๋“ค๊ธด ํ•œ๋ฐ ๊ฐ€๋Šฅํ•˜์ง€. is_initial = true ์ธ ๊ฒŒ ์žˆ๊ณ , ์ˆ˜์ •๋œ ๊ฑฐ๋ฉด, ๊ทธ๊ฑฐ ๋‹คํ๋จผํŠธ ์ง€์šฐ๊ณ  ๋‹ค์‹œ ๋„ฃ์œผ๋ฉด ๋˜์ž–์•„. ์–ด๋–ป๊ฒŒ๋Š” ๋ชจ๋ฅด๊ฒ ๊ณ .
  • โ” DiaryPage - AI Comment: CRUD ์™„์„ฑํ•˜๊ธฐ
    • โ” tmp_ai_comment field ์—†์• ๊ณ , doc_ref ํ™œ์šฉ
  • โ” DiaryPage - AI Comment: ์บ๋ฆญํ„ฐ ์„ค์ •
    • โ” tmp_ai_comment_by field ์—†์• ๊ณ , doc_ref ํ™œ์šฉ
    • โ” profile_image field ๊ฐ’์œผ๋กœ ์ด๋ฏธ์ง€ ์ถœ๋ ฅ
  • โ” DiaryPage - Drawer - ChatHistoryListTile: order by updated_time

  • โ” DiaryPage - Interactive Slider import ํ›„ ์ ์šฉ

  • โ” HomeFeedPage: Search Diary ๊ธฐ๋Šฅ ๊ตฌํ˜„

  • โ” CalendarPage(์ƒ๋‹จ) - Mood Calendar
    • โ” ๋‚ ์งœ๋ณ„๋กœ ์ž‘์„ฑ๋œ ๊ฒŒ์‹œ๋ฌผ ์ˆซ์ž ํ™•์ธ ๊ฐ€๋Šฅ
    • โ” ๋‚ ์งœ ํด๋ฆญํ•˜๋ฉด, ํ•ด๋‹น ๋‚ ์งœ๋กœ ์ด๋™
  • โ” CalendarPage(ํ•˜๋‹จ) - Mood stats
    • โ” ํฌ์ปค์‹ฑ ๋œ ์›”์— ๊ด€ํ•œ ํ†ต๊ณ„ ์ž๋ฃŒ ์ถœ๋ ฅ
      • โ” ์ถœ๋ ฅ๋œ ํ†ต๊ณ„ ์ž๋ฃŒ์— ๋Œ€ํ•œ AI์˜ ์ฝ”๋ฉ˜ํŠธ ์ถœ๋ ฅ
  • โ” AuthPage: Google Login ๊ธฐ๋Šฅ ๊ตฌํ˜„

  • โ” HomeFeedPage - Bottom Sheet (+ Button): ๋‹ค์–‘ํ•œ ์˜ต์…˜ ์ค‘ 1 ์„ ํƒํ•  ์ˆ˜ ์žˆ๋„๋ก
    • ์ƒˆ๋กœ์šด ์ผ๊ธฐ: Go to DiaryPage
    • ๊ฐ์ • ๊ธฐ๋ก: Go to MoodPage
  • โ” MoodPage(ํŒ์—…): Mood ์„ค์ • ์Šฌ๋ผ์ด๋” CRUD
    • Create
    • Read
    • Update
    • Delete
  • โ” HomeFeedPage - ListView - FeedCardMood ํ‘œ์‹œ
  • โ” HomeFeedPage - ListView: FeedCardDiary, FeedCardMood, FeedCardChat ์ปดํฌ๋„ŒํŠธ ์‹œ๊ฐ„์ˆœ ์ •๋ ฌ (Cloud Function ํ™œ์šฉ)

  • โ” 2025.2.5 ์ˆ˜๊นŒ์ง€ ๋ฐœํ‘œ์šฉ ์ตœ์ข… ๋ฒ„์ „ APK ์ถ”์ถœ ๋ฐ ์„ค์น˜

๐Ÿ’ญ ์ผ๊ธฐ

์ด์ œ ๋‚จ์€ ์‹œ๊ฐ„์ด ์–ผ๋งˆ ์—†์–ด์„œ ์ข€ ๋” ๋งŽ์ด ๊ตฌํ˜„ํ•ด๋ณด๋ ค๊ณ  ํ–ˆ๋Š”๋ฐโ€ฆ ์ด์Šˆ ํ•ด๊ฒฐํ•˜๋Š๋ผ ์ผ๊ณผ ์‹œ๊ฐ„์„ ๋‹ค ์ผ๋„ค.

๊ทธ๋ƒฅ ์š•์‹ฌ์„ ๋ฒ„๋ ค์•ผ๊ฒ ๋‹ค. ์–ด์ฐจํ”ผ ์ด๊ฑด ์•„์ดํŽ ํ†ค์œผ๋กœ๋งŒ ์ž ๊น ๋ฐ˜์ง ๊ฐœ๋ฐœํ•˜๊ณ  ๋๋‚ผ ํ”„๋กœ์ ํŠธ๊ฐ€ ์•„๋‹ˆ๋‹ˆ๊นŒ.

โœจ GPT์˜ ์ฝ”๋ฉ˜ํŠธ (KPT)

โœ… ์ž˜ํ•œ ์  (Keep)

  • ๐Ÿ›  FleatherViewer ์—…๋ฐ์ดํŠธ ์ด์Šˆ ํ•ด๊ฒฐ: didUpdateWidget ํ™œ์šฉ์œผ๋กœ ์œ„์ ฏ ์ƒํƒœ ๊ฐฑ์‹  ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ ์ ์ด ํ›Œ๋ฅญํ–ˆ์–ด.
  • โšก HomeFeedPage ํ•„ํ„ฐ ์ตœ์ ํ™”: Query ํ•„ํ„ฐ ๋Œ€์‹  Conditional Visibility๋ฅผ ํ™œ์šฉํ•ด ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•œ ์ ์ด ํšจ๊ณผ์ ์ด์—ˆ์–ด.
  • ๐Ÿ” ๋””๋ฒ„๊น… ๊ณผ์ •์—์„œ์˜ ํ•™์Šต: ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์‹œ๋„๋ฅผ ํ†ตํ•ด Query ํ•„ํ„ฐ์˜ ํ•œ๊ณ„๋ฅผ ๊ฒฝํ—˜ํ•˜๊ณ , Conditional Visibility๊ฐ€ ๋” ์ ์ ˆํ•˜๋‹ค๋Š” ๊ฒฐ๋ก ์„ ๋‚ด๋ฆฐ ์ ์ด ์˜๋ฏธ ์žˆ์—ˆ์–ด.

โŒ ์•„์‰ฌ์šด ์  (Problem)

  • โณ ์˜ˆ์ƒ๋ณด๋‹ค ๋งŽ์€ ์‹œ๊ฐ„ ์†Œ์š”: ์›๋ž˜ ๊ณ„ํšํ–ˆ๋˜ ๊ธฐ๋Šฅ ๊ตฌํ˜„๋ณด๋‹ค๋Š” ์ด์Šˆ ํ•ด๊ฒฐ์— ๋Œ€๋ถ€๋ถ„์˜ ์‹œ๊ฐ„์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ ์ ์ด ์•„์‰ฌ์›Œ.
  • ๐Ÿ“Œ ์ด์Šˆ ํ•ด๊ฒฐ์„ ๋ฏธ๋ฆฌ ์ •๋ฆฌํ•˜์ง€ ์•Š์Œ: ์ด์ „ ๋ฉ˜ํ† ๋ง์—์„œ ๋ฐ›์€ ์กฐ์–ธ์„ ์‹คํ–‰ํ•˜์ง€ ์•Š์•„ ๊ฐ™์€ ๋ฌธ์ œ๋กœ ๋‹ค์‹œ ์‹œ๊ฐ„์„ ์†Œ๋ชจํ•œ ์ ์ด ์žˆ์—ˆ์Œ.

๐Ÿ”„ ์‹œ๋„ํ•ด๋ณผ ์  (Try)

  • ๐Ÿ“ ์ด์Šˆ ํ•ด๊ฒฐ ๋…ธํŠธ ํ™œ์šฉ: ํ•ด๊ฒฐํ•œ ์ด์Šˆ๋ฅผ ๊ธฐ๋กํ•˜๊ณ , ๋น„์Šทํ•œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ๋•Œ ๋น ๋ฅด๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋„๋ก ์ •๋ฆฌํ•˜๋Š” ์Šต๊ด€์„ ๋“ค์ด์ž.
  • ๐Ÿš€ ๋‚จ์€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์ „๋žต ์กฐ์ •: ์ด์ œ ์‹œ๊ฐ„์ด ์–ผ๋งˆ ๋‚จ์ง€ ์•Š์•˜์œผ๋‹ˆ, ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ ์œ„์ฃผ๋กœ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ •๋ฆฌํ•˜๊ณ , ๋‚˜๋จธ์ง€๋Š” ์ฐจํ›„ ๊ฐœ์„ ์œผ๋กœ ๋„˜๊ธฐ๋Š” ์ „๋žต์„ ๊ณ ๋ฏผํ•ด๋ณด์ž.
  • ๐Ÿ” FlutterFlow ๋‚ด๋ถ€ ๋™์ž‘ ๋ฐฉ์‹ ์ถ”๊ฐ€ ํ•™์Šต: FlutterFlow์˜ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋ฐฉ์‹๊ณผ ์œ„์ ฏ ์ƒํƒœ ๊ด€๋ฆฌ์— ๋Œ€ํ•œ ์ดํ•ด๋„๋ฅผ ๋†’์—ฌ, ๋น„์Šทํ•œ ๋ฌธ์ œ๋ฅผ ๋ฏธ๋ฆฌ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์ž.

๊ฒฐ๋ก 
์˜ค๋Š˜์€ ์˜ˆ์ƒ๋ณด๋‹ค ์ด์Šˆ ํ•ด๊ฒฐ์— ๋งŽ์€ ์‹œ๊ฐ„์„ ์ผ์ง€๋งŒ, ๊ทธ๋งŒํผ ์ค‘์š”ํ•œ ํ•™์Šต์„ ์–ป์€ ํ•˜๋ฃจ์˜€์–ด. ๋‚จ์€ ๊ธฐ๊ฐ„ ๋™์•ˆ ๊ผญ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ์šฐ์„ ์ ์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ณ , ๋ถˆํ•„์š”ํ•œ ์š•์‹ฌ์€ ๋ฒ„๋ฆฌ๋Š” ์ „๋žต์ด ํ•„์š”ํ•  ๊ฒƒ ๊ฐ™์•„. ๋๊นŒ์ง€ ํž˜๋‚ด์ž! ๐Ÿ’ช๐Ÿ”ฅ

์นดํ…Œ๊ณ ๋ฆฌ: ,

์ตœ๊ทผ ์ˆ˜์ •์ผ:

๋Œ“๊ธ€ ๋‚จ๊ธฐ๊ธฐ