DB 설계, 기능 구현 및 UI UX관련

Description: 해당 프로젝트를 구현하면서 고민하고 구현한 내용위주로 담긴 글입니다.

현재 노트: KR-110.40 b DB 설계, 기능 구현 및 UI UX관련
상위 분류: KR-110.40 생성형 AI를 이용한 개인 창작 마법 프로젝트

#개인프로젝트

DB 설계하기

DB설계시 어떤 데이터 즉 column이 설계하지를 고민해보고 어떤 타입을 넣을지도 고민했습니다.
추가적으로 새로운 column이 생길때 추가 하는 방법과, null값 허용여부에 따라 새로생기는 데이터에 에러가 생기는 경우를 처리했습니다.
다른 테이블과읜 관계를 통해 owner_id를 기존의 테이블에서 참조하는 형태의 테이블도 만들었습니다. 이 과정에서 테이블끼리의 연관관계를 표현하기에 어떤 데이터이름과 어떤 column을 선정하는 것이 적합한지에 대한 고민도 해보았습니다.

DB1 초기 Backend Schema

CREATE TABLE IF NOT EXISTS public.users
(
    id integer NOT NULL DEFAULT nextvalregclass,
    username text COLLATE pg_catalog."default" NOT NULL,
    password text COLLATE pg_catalog."default",
    email text COLLATE pg_catalog."default",
    created_at timestamp with time zone DEFAULT now(),
    updated_at timestamp with time zone DEFAULT now(),
}

DB2 Mana (int) 추가

ALTER TABLE users ADD COLUMN mana INTEGER DEFAULT 10;

DB3 social login위한 twitter_id column 추가

ALTER TABLE users ADD COLUMN IF NOT EXISTS twitter_id TEXT UNIQUE;

DB4 password null 값 허용으로 변경

ALTER TABLE public.users ALTER COLUMN password DROP NOT NULL;

Card Table생성

CREATE TABLE cards (
    id SERIAL PRIMARY KEY,                  -- Unique ID, auto-increment
    name VARCHAR(255) NOT NULL,             -- Card name
    cost VARCHAR(50) NOT NULL,              -- Card cost
    damage VARCHAR(50),                     -- Card damage
    effect TEXT,                            -- Card effect
    type VARCHAR(50),                       -- Card type
    description TEXT,                       -- Card description
    link TEXT,                              -- Link attribute (additional link or related URL)
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,  -- Creation date
    owner_user_id INT REFERENCES users(id) ON DELETE SET NULL ON UPDATE CASCADE, -- Owner user ID (foreign key linked to the users table)
    group_name VARCHAR(255)                 -- Group or organization the card belongs to
);

초기 Backend 페이지

스크린샷 2024-09-26 152310.png

Front 홈 페이지 첫 CSS 적용 후

학습초기 CSS를 사용하여 서비스에 적용해본 결과물이었습니다.
각 로그인화면에서 다른 색깔을, 버튼별 색깔지정을 통해 UX를 위한 디자인을 생각해보았습니다.

스크린샷 2024-09-26 153932.png

Front 첫 로그인페이지

스크린샷 2024-09-26 180040.png

Login 후 Delete ID 추가

Delete ID를 구현한 후 적용 화면입니다.

Pasted image 20240928142015.png

첫 트위터 소셜 로그인 기능 구현

소셜 로그인을 위해 어떤 방법으로 구현할까를 고민하였습니다. 기존의 게스트로그인이나 회원가입 로그인을 응용하는 방식이 있을텐데 그 중에서 적합한 것이 어떤 방법인가 고민을 해봤을 때 답이 안나와 레퍼런스를 확인하였습니다.
어떤 의미로 게스트 로그인의 경우 회원로그인에서 임의로 값이 채워진채 자동으로 만들어진 방식이라는 점에 착안하여, 소설 로그인또한 회원로그인이지만 임의의 값이 채워진 회원로그인 이라는 형태로 생각하여 구현했습니다.
Pasted image 20240928194545.png

로그인한 유저이름 표시

각 유저별 이름을 표시하는 기능을 구현한 이미지입니다. 해당 기능의 중요한 점은 가지고 오는 유저이미지가 DB의 값에 등록된 회원의 이름 정보를 이용한다는 점이었습니다.
Pasted image 20240928223209.png

첫 system prompt

중요한 시스템 프롬프트입니다. chatgpt와 같은 AI에게 원하는 대답을 얻게하기 위해 사전에 설정된 세계관 같은 내용을 시스템 프롬프트로서 입력하게 됩니다.

"In a magical world, users provide a simple string and a mana value as input. **If no mana is mentioned, the default input mana is 10.** Based on this string, a magic spell is created with the following attributes:\n\n- **Description**: Depicts the spell's appearance based on the input prompt, including aspects like size, shape, color, patterns, and similarities to objects or scenarios.\n- **Attack Power**: A numerical value representing the spell's offensive strength.\n- **Cost**: A numerical value indicating the mana required to cast the spell.\n- **Effect**: A narrative description of what the spell does.\n- **Type**: Assigns an appropriate attribute to the spell. Common elements like fire, water, grass, and earth are acceptable, but depending on the description, it can also include diverse attributes like mirror, blood, darkness, time, fluid, etc.\n- **Name**: A concise summary of the spell.\n\nAll spells vary in power based on the mana input, even under the same conditions. For example, with the same prompt, a spell created with mana 1 and mana 10 will differ significantly in attack power, cost, description, name, and effect.\n\n**Example:**\n\nInput prompt: *\"fire ball with soccer ball\"*\n\nMana: **1**\n\n- **Name**: Fire Soccer Ball\n- **Attack Power**: 10\n- **Cost**: 2\n- **Description**: A small fireball about the size of a soccer ball that looks incomplete. It has great offense but can also explode when cast.\n- **Effect**: The caster has a chance to take damage themselves.\n- **Type**: Fire"

첫 프롬프트및이미지 기능통합

프롬프트의 텍스트데이터를 파이프라인처럼 연동하여 최종적으로 생성되는 이미지의 입력으로 받게합니다. termination keyword를 통해 대화기능의 종료와 이미지 생성의 호출을 수행하게됩니다.
Pasted image 20241018010439.png

대화창 유저랑 봇 대답 구분

유저 경험을 향상시키기 위해 UX적으로 유저가 입력한 대화와 봇이 대답한 대답을 구분합니다.

변경전
Pasted image 20241204033105.png

변경후 message의 role에따라 구분
Pasted image 20241204033028.png

시스템 프롬프트 업데이트

시스템프롬프트의 경우 대답과 기능에 따라 자주 바뀔 수 있습니다. 이번 경우처럼 multiturn을 위해 여러번 대화를 하는 상황을전제로 하는 시스템 프롬프트를 구현합니다.

You are the history that creates the magic. You create new magic with the input of your users. 

You'll be asked 4 questions by default.
If you need more, you'll be asked up to 4 more questions.
Finally, you'll be asked 1 question.

The 4 basic questions
1. What kind of personality are you?
2. What is your current state of mind?
3. What is your intention in creating this magic?
4. What do you consider to be the most important aspect of this spell?

(additional questions as needed, usually not necessary)

final question
Describe your magic.
{

    "Name": <spell name>,
    "Cost": <mana cost int>,
    "Damage": <damage int>,
    "Effect": <effect of a card>,
    "Type": <types of a card>,
    "Rarity": <common | uncommon | rare | unique | regendary |ancient |custom | ego>,
    "Description": < description of spell>

};

대화창 유저랑 봇 대답 구분
변경전
Pasted image 20241204033105.png

변경후 message의 role에따라 구분
Pasted image 20241204033028.png