๋ชจ๋ํ๋ Spring Boot ๊ธฐ๋ฐ ๋ฐฑ์๋ ํ๋ซํผ. ์ธ์ฆ/์ธ๊ฐ, ์ฌ์ฉ์/๊ทธ๋ฃน ๊ด๋ฆฌ, ํ์ผยท์ฒจ๋ถ ๊ด๋ฆฌ, ํ ํ๋ฆฟ, ๋ฉ์ผ, ์ค์๊ฐ ๋ฉ์์ง, AI ์๋ฒ ๋ฉ/RAG ํ์ดํ๋ผ์ธ์ ๊ณตํต ์ปดํฌ๋ํธ์ ์คํํฐ๋ก ์ ๊ณตํ๋ค.
- JDK 17๊ณผ Gradle ์คํ ํ๊ฒฝ์ ์ค๋นํ๋ค.
- ํ์ํ secret์ ์
ธ ํ๊ฒฝ๋ณ์ ๋๋ ๋ก์ปฌ ์ ์ฉ
~/.gradle/gradle.properties์ ๋ฃ๋๋ค. - ๋ฃจํธ์์
./gradlew clean build๋ฅผ ์คํํ๋ค. - ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ํ์ํ starter๋ง ์ ํํด ์์กด์ฑ์ ์ถ๊ฐํ๋ค.
์ต์ ํ์ธ์ฉ ๋ช ๋ น:
./gradlew clean buildํ์ secret ์์๋ .env.example์์ ํ์ธํ๋ค.
- Java toolchain / source compatibility:
17 - Spring Boot:
3.5.9 - Spring Dependency Management Plugin:
1.1.7 - Build:
Gradle Wrapper
starter/ # Spring Boot ์คํํฐ ๋ชจ์ (์๋ ๊ตฌ์ฑ)
studio-application-modules/ # ์ ํ๋ฆฌ์ผ์ด์
๊ธฐ๋ฅ ๋ชจ๋ (attachment, avatar, embedding pipeline, template, mail)
studio-platform/ # ์ฝ์ด ํ๋ซํผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
studio-platform-objecttype/ # objectType ๋ ์ง์คํธ๋ฆฌ/์ ์ฑ
/๋ฐํ์ ๊ฒ์ฆ ๊ตฌํ
studio-platform-ai/ # AI/RAG ๊ณตํต ๊ณ์ฝ๊ณผ ํฌํธ
studio-platform-chunking/ # RAG indexing์ฉ chunking ๊ณ์ฝ
studio-platform-autoconfigure/ # ๊ณตํต ์๋ ๊ตฌ์ฑ
studio-platform-data/ # ๋ฐ์ดํฐ ์ก์ธ์ค ๊ณตํต
studio-platform-identity/ # ์ธ์ฆ/์๋ณ ์ถ์ํ(๊ณ์ฝ)
studio-platform-security(+acl)/ # ๋ณด์ + ACL
studio-platform-realtime/ # ์ค์๊ฐ ๊ธฐ๋ฅ(์น์์ผ ๋ฑ) ๊ณตํต
studio-platform-storage/ # ์ค๋ธ์ ํธ ์คํ ๋ฆฌ์ง ๊ณตํต
studio-platform-user/ # ์ฌ์ฉ์/๊ทธ๋ฃน/์ญํ /ํ์ฌ ๋๋ฉ์ธ (๊ณ์ฝ)
studio-platform-user-default/ # ์ฌ์ฉ์ ๊ธฐ๋ณธ ๊ตฌํ (์ํฐํฐ/๋ฆฌํฌ์งํ ๋ฆฌ/์๋น์ค/์ปจํธ๋กค๋ฌ)
studio-platform: ๊ณตํต ์น/์์ธ/๋๋ฉ์ธ ๊ณ์ฝstudio-platform-security,studio-platform-security-acl: ์ธ์ฆ/์ธ๊ฐ, JWT, ACLstudio-platform-user,studio-platform-user-default: ์ฌ์ฉ์ ๊ณ์ฝ๊ณผ ๊ธฐ๋ณธ ๊ตฌํstudio-platform-data,studio-platform-objecttype,studio-platform-realtime: ๋ฐ์ดํฐ, objectType, ์ค์๊ฐ ๊ธฐ๋ฅ ๊ณตํตstudio-platform-ai,studio-platform-chunking,studio-platform-storage,studio-platform-identity: AI/RAG ๊ณ์ฝ, chunking ๊ณ์ฝ, ์ ์ฅ์, ์๋ณ ๊ณตํตstudio-application-modules/*: attachment, avatar, embedding pipeline, template, mail
์ธ๋ถ ์ค์ , ์๋ํฌ์ธํธ, ํ์ฅ ํฌ์ธํธ๋ ๊ฐ ๋ชจ๋ README๋ฅผ ์ฐธ๊ณ ํ๋ค.
๊ฐ ๊ธฐ๋ฅ์ ๋์๋๋ ์คํํฐ๋ฅผ ์ถ๊ฐํ๋ฉด ์๋ ๊ตฌ์ฑ๋๋ค. ์์ฝ์ starter/README.md ์ฐธ๊ณ .
์์:
dependencies {
implementation(project(":starter:studio-platform-starter")) // ํ๋ซํผ ๊ธฐ๋ณธ
implementation(project(":starter:studio-platform-starter-security")) // ๋ณด์
implementation(project(":starter:studio-platform-starter-user")) // ์ฌ์ฉ์
implementation(project(":starter:studio-platform-starter-objecttype")) // objectType
implementation(project(":starter:studio-application-starter-attachment")) // ์ฒจ๋ถ
}๋ํ์ ์ธ ์ ํ ๊ธฐ์ค:
- ๊ณตํต ์น/๋ฐ์ดํฐ/JPA ๊ธฐ๋ฐ์
:starter:studio-platform-starter - ์ธ์ฆ/์ธ๊ฐ๊ฐ ํ์ํ๋ฉด
:starter:studio-platform-starter-security - ์ฌ์ฉ์ ๊ธฐ๋ณธ ๊ตฌํ๊น์ง ํ์ํ๋ฉด
:starter:studio-platform-starter-user์:studio-platform-user-default - objectType ์ ์ฑ
/๊ฒ์ฆ์ด ํ์ํ๋ฉด
:starter:studio-platform-starter-objecttype - STOMP/WebSocket ์ค์๊ฐ ์๋ฆผ์ด ํ์ํ๋ฉด
:starter:studio-platform-starter-realtime - ์ฒจ๋ถ/์๋ฐํ/ํ ํ๋ฆฟ/๋ฉ์ผ ๊ฐ์ ๊ธฐ๋ฅ ๋ชจ๋์ ๊ฐ application starter๋ฅผ ์ถ๊ฐ
- RAG indexing์ฉ chunking ์ ๋ต์ด ํ์ํ๋ฉด
:starter:studio-platform-starter-chunking
๋ํ ์กฐํฉ ์์:
// ๊ธฐ๋ณธ ์ธ์ฆ ์ฑ
implementation(project(":starter:studio-platform-starter"))
implementation(project(":starter:studio-platform-starter-security"))
implementation(project(":starter:studio-platform-starter-user"))
implementation(project(":studio-platform-user-default"))
// ์ฒจ๋ถ + AI ์๋ฒ ๋ฉ ์ฑ
implementation(project(":starter:studio-application-starter-attachment"))
implementation(project(":studio-application-modules:content-embedding-pipeline"))
implementation(project(":starter:studio-platform-starter-chunking"))
implementation(project(":starter:studio-platform-starter-ai"))
implementation("org.springframework.ai:spring-ai-starter-model-openai")
// ์ค์๊ฐ ์๋ฆผ ์ฑ
implementation(project(":starter:studio-platform-starter-realtime"))
implementation("org.springframework.boot:spring-boot-starter-data-redis")
// ํ
ํ๋ฆฟ + ๋ฉ์ผ ์ฑ
implementation(project(":starter:studio-application-starter-template"))
implementation(project(":starter:studio-application-starter-mail"))studio-platform-starter-ai๋ provider ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ compileOnly๋ก๋ง ์ ๊ณตํ๋ฏ๋ก,
์๋น ์ฑ์์ ํ์ํ provider๋ฅผ ์ง์ ์ ์ธํด์ผ ํ๋ค. Spring AI BOM์ api(platform(...))์ผ๋ก
๋
ธ์ถ๋๋ฏ๋ก ๋ณ๋ BOM ์ ์ธ ์์ด ์ผ๊ด๋ Spring AI ๋ฒ์ ์ ์ฌ์ฉํ ์ ์๋ค.
// OpenAI ์ฌ์ฉ ์์
implementation(project(":starter:studio-platform-starter-ai"))
implementation("org.springframework.ai:spring-ai-starter-model-openai")
// Google GenAI ์ฌ์ฉ ์์
implementation(project(":starter:studio-platform-starter-ai"))
implementation("org.springframework.ai:spring-ai-google-genai")
// Ollama ์ฌ์ฉ ์์
implementation(project(":starter:studio-platform-starter-ai"))
implementation("org.springframework.ai:spring-ai-ollama")์์กด์ฑ์ ์๋ ๋ฐฉํฅ์ ๊ถ์ฅํ๋ค. (์ํ ์์กด ๊ธ์ง)
studio-platform
โ studio-platform-objecttype
โ studio-platform-data
studio-platform
โ studio-platform-security
โ studio-platform-security-acl
studio-platform
โ studio-platform-user
โ studio-platform-user-default
studio-platform
โ studio-platform-ai
studio-platform
โ studio-platform-realtime
โ studio-platform-storage
starter
โ platform modules
โ application modules
application modules
โ platform modules
- ์คํํฐ๋ฅผ ํตํด ํ์ํ ๊ธฐ๋ฅ๋ง ํ์ฑํํ๋ค.
- ์ธ๋ถ ์น/API ๊ท์น์
studio-platform/WEB_API_DEVELOPMENT_GUIDE.md๋ฅผ ๋ฐ๋ฅธ๋ค. - ACL ์ธ๋ถ ์ฐ๋์
studio.one.platform.security.acl.AclPermissionService์ธํฐํ์ด์ค๋ง ์์กดํ๋ค.
./gradlew clean build๋ชจ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํํ๋ก ๋ฐฐํฌ๋๋ฉฐ, ์คํํฐ๋ฅผ ์ฌ์ฉํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์กด์ฑ์ ์ถ๊ฐํด ์คํํ๋ค.
๋ก์ปฌ์ Gradle์ด ์ค์น๋์ด ์๊ณ wrapper ํ์ผ์ ๋ค์ ๋ง๋ค๊ณ ์ถ์ผ๋ฉด ๋ค์ ๋ช ๋ น์ ์ฌ์ฉํ ์ ์๋ค.
gradle wrapper๊ฐ๋ณ ๋ชจ๋๋ง ํ์ธํ ๋๋ ๋ค์์ฒ๋ผ ์คํํ ์ ์๋ค.
./gradlew :studio-platform:build
./gradlew :studio-application-modules:attachment-service:test๊ฐ๋ฐ ์ค ๋ก์ปฌ Nexus์ ๋ฐฐํฌํ ๋๋ gradle.properties๋ฅผ ์์ ํ์ง ๋ง๊ณ ๋ก์ปฌ ๋ฐฐํฌ ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ๋ค.
์คํฌ๋ฆฝํธ๋ ๊ธฐ๋ณธ์ ์ผ๋ก .env.local์ ์ฝ์ผ๋ฉฐ, ์ด๋ฏธ ์
ธ์ ์ค์ ๋ ํ๊ฒฝ๋ณ์๋ ๋ฎ์ด์ฐ์ง ์๋๋ค.
NEXUS_USERNAME=...
NEXUS_PASSWORD=...
scripts/publish-local-nexus.shํน์ ๋ชจ๋๋ง ๋ฐฐํฌํ ๋๋ Gradle task๋ฅผ ๊ทธ๋๋ก ์ ๋ฌํ๋ค.
scripts/publish-local-nexus.sh :studio-platform-user:publish๋ก์ปฌ Nexus์ ๊ฐ์ ๋ฒ์ ์ด ์ด๋ฏธ ์ฌ๋ผ๊ฐ ์์ด ์ญ์ ํ ๋ค์ ๋ฐฐํฌํด์ผ ํ ๋๋ --delete-existing์ ์ฌ์ฉํ๋ค.
์ด ์ต์
๋ง ์ง์ ํ๋ฉด settings์ ํฌํจ๋ ์ ์ฒด ๋ชจ๋์ ํ์ธํ๊ณ , ๊ธฐ์กด component๊ฐ ์๋ ๊ฒฝ์ฐ ์ญ์ ํ ๋ค ๊ธฐ๋ณธ publish๋ฅผ ์คํํ๋ค.
scripts/publish-local-nexus.sh --delete-existingํน์ ๋ชจ๋๋ง ์ญ์ ํ ์ฌ๋ฐฐํฌํ ๋๋ ๋์ ๋ชจ๋์ ๋ช ์ํ๋ค.
scripts/publish-local-nexus.sh --delete-existing --module :studio-platform-user์ด ์คํฌ๋ฆฝํธ๋ ๊ธฐ๋ณธ์ ์ผ๋ก http://localhost:8081/repository/maven-releases/์
http://localhost:8081/repository/maven-snapshots/๋ฅผ ์ฌ์ฉํ๋ฉฐ, repository URL๊ณผ
nexus.allowInsecure=true ๊ฐ์ Gradle project property๋ก ์ ๋ฌํ๋ค.
๋ก์ปฌ Nexus base URL์ด ๋ค๋ฅด๋ฉด NEXUS_URL ํ๊ฒฝ๋ณ์๋ก ๋ณ๊ฒฝํ ์ ์๋ค.
๋ค๋ฅธ env ํ์ผ์ ์ฐ๋ ค๋ฉด --env-file <path>๋ฅผ ์ ๋ฌํ๋ค.
- secret์ ์ ์ฅ์์ ์ปค๋ฐํ์ง ์๊ณ ํ๊ฒฝ๋ณ์ ๋๋
~/.gradle/gradle.properties๋ก๋ง ์ฃผ์ ํ๋ค. - ์ํ ํ๊ฒฝ๋ณ์ ๋ชฉ๋ก์ .env.example, ์์ธ ์ด์ ๊ท์น๊ณผ ํ์ ์ ์ฐจ๋ SECURITY.md๋ฅผ ์ฐธ๊ณ ํ๋ค.
์์ฃผ ํ์ํ ๊ฐ:
STUDIO_JWT_SECRETJASYPT_ENCRYPTOR_PASSWORDJASYPT_HTTP_TOKENOPENAI_API_KEYNEXUS_USERNAME,NEXUS_PASSWORD
| ํ๊ฒฝ๋ณ์ | ๊ด๋ จ ๊ธฐ๋ฅ/์คํํฐ | ๋ฏธ์ค์ ์ ๋์ |
|---|---|---|
STUDIO_JWT_SECRET |
studio-platform-starter-security |
JWT ํ์ฑํ ์ ๊ธฐ๋ ์คํจ |
JASYPT_ENCRYPTOR_PASSWORD |
studio-platform-starter-jasypt |
์ํธํ ํ๋กํผํฐ ๋ณตํธํ ์คํจ |
JASYPT_HTTP_TOKEN |
studio-platform-starter-jasypt |
๋ด๋ถ Jasypt HTTP ์๋ํฌ์ธํธ ๋ณดํธ ํ ํฐ์ผ๋ก ์ฌ์ฉ |
OPENAI_API_KEY |
studio-platform-starter-ai + OpenAI provider |
OpenAI provider ํ์ฑํ ์ ๊ธฐ๋ ์คํจ |
GOOGLE_API_KEY ๋๋ GOOGLE_AI_API_KEY |
studio-platform-starter-ai + Google GenAI provider |
Google provider ํ์ฑํ ์ ๊ธฐ๋ ์คํจ |
NEXUS_USERNAME, NEXUS_PASSWORD, NEXUS_URL |
scripts/publish-local-nexus.sh |
๋ก์ปฌ Nexus ๋ฐฐํฌ ์คํฌ๋ฆฝํธ ์คํจ |
studio:
persistence:
type: jpa # jpa|jdbc
features:
attachment:
enabled: true
web:
enabled: true
base-path: /api/mgmt/attachments
storage:
type: filesystem # filesystem|database
cache-enabled: false
avatar-image:
enabled: true
user:
enabled: true
web:
enabled: true
security-acl:
enabled: true
cache-name: aclCache
admin-role: ROLE_ADMIN
use-spring-acl: false
metrics-enabled: true
audit-enabled: true
ai:
enabled: true
default-provider: openai # ํ์ โ ๋ฏธ์ค์ ์ ๊ธฐ๋ ์คํจ
providers:
openai:
type: OPENAI
chat:
enabled: true
embedding:
enabled: true
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
chat:
options:
model: gpt-4o-mini
embedding:
options:
model: text-embedding-3-smallํ์ ์๋ ๊ธฐ๋ฅ์ enabled=false ๋ก ๋นํ์ฑํํ๊ณ , ๊ฒฝ๋ก๋ ์ ์ฅ์ ํ์
์ studio.features.<feature>.* ์์ฑ์ผ๋ก ์กฐ์ ํ๋ค.
- ์คํํฐ ์์ฝ:
starter/README.md - AI ํด๋ผ์ด์ธํธ ์์ ๊ฐ์ด๋:
docs/dev/ai-client-update-guide.md - ์ ํ๋ฆฌ์ผ์ด์
๋ชจ๋ ๊ฐ์ด๋:
studio-application-modules/README.md - ์ฌ์ฉ์ ๊ณ์ฝ:
studio-platform-user/README.md - ์ฌ์ฉ์ ๊ธฐ๋ณธ ๊ตฌํ:
studio-platform-user-default/README.md - ๋ณ๊ฒฝ ์ด๋ ฅ:
CHANGELOG.md(2.x๋ผ์ธ๋ถํฐ ์ ๊ธฐ์ค์ผ๋ก ๊ด๋ฆฌ) - ๋ณด์ ์ด์ ๊ท์น:
SECURITY.md - ํ๋ซํผ ์น ๊ท์น:
studio-platform/WEB_API_DEVELOPMENT_GUIDE.md - ์ค์ ๋ค์์คํ์ด์ค ๊ฐ์ด๋:
CONFIGURATION_NAMESPACE_GUIDE.md
- ํ๋ซํผ ๊ณตํต:
studio-platform,studio-platform-data,studio-platform-autoconfigure,studio-platform-identity - ๋ณด์:
studio-platform-security,studio-platform-security-acl - ์ฌ์ฉ์:
studio-platform-user,studio-platform-user-default - ๋ถ๊ฐ๊ธฐ๋ฅ:
studio-platform-objecttype,studio-platform-realtime,studio-platform-storage,studio-platform-ai - ์ ํ๋ฆฌ์ผ์ด์
๋ชจ๋:
attachment-service,avatar-service,content-embedding-pipeline,template-service,mail-service