Skip to content

Commit

Permalink
release: 0.9.7 (#212)
Browse files Browse the repository at this point in the history
  • Loading branch information
devxb authored Dec 23, 2024
2 parents 8c016d5 + debf5b1 commit 705f52f
Show file tree
Hide file tree
Showing 67 changed files with 2,731 additions and 125 deletions.
21 changes: 21 additions & 0 deletions src/main/kotlin/org/gitanimals/guild/app/AcceptJoinGuildFacade.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.gitanimals.guild.app

import org.gitanimals.guild.domain.GuildService
import org.springframework.stereotype.Service

@Service
class AcceptJoinGuildFacade(
private val identityApi: IdentityApi,
private val guildService: GuildService,
) {

fun acceptJoin(token: String, guildId: Long, acceptUserId: Long) {
val user = identityApi.getUserByToken(token)

guildService.acceptJoin(
acceptorId = user.id.toLong(),
guildId = guildId,
acceptUserId = acceptUserId,
)
}
}
22 changes: 22 additions & 0 deletions src/main/kotlin/org/gitanimals/guild/app/ChangeGuildFacade.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.gitanimals.guild.app

import org.gitanimals.guild.domain.GuildService
import org.gitanimals.guild.domain.request.ChangeGuildRequest
import org.springframework.stereotype.Service

@Service
class ChangeGuildFacade(
private val identityApi: IdentityApi,
private val guildService: GuildService,
) {

fun changeGuild(token: String, guildId: Long, changeGuildRequest: ChangeGuildRequest) {
val user = identityApi.getUserByToken(token)

guildService.changeGuild(
changeRequesterId = user.id.toLong(),
guildId = guildId,
request = changeGuildRequest,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.gitanimals.guild.app

import org.gitanimals.guild.domain.GuildService
import org.springframework.stereotype.Component

@Component
class ChangeMainPersonaFacade(
private val renderApi: RenderApi,
private val identityApi: IdentityApi,
private val guildService: GuildService,
) {

fun changeMainPersona(token: String, guildId: Long, personaId: Long) {
val user = identityApi.getUserByToken(token)
val personas = renderApi.getUserByName(user.username).personas

val changedPersona = personas.firstOrNull { it.id.toLong() == personaId }
?: throw IllegalArgumentException("Cannot change persona to \"$personaId\" from user \"${user.username}\"")

guildService.changeMainPersona(
guildId = guildId,
userId = user.id.toLong(),
personaId = changedPersona.id.toLong(),
personaType = changedPersona.type,
)
}
}
100 changes: 100 additions & 0 deletions src/main/kotlin/org/gitanimals/guild/app/CreateGuildFacade.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package org.gitanimals.guild.app

import org.gitanimals.guild.app.request.CreateGuildRequest
import org.gitanimals.guild.domain.GuildService
import org.gitanimals.guild.domain.request.CreateLeaderRequest
import org.rooftop.netx.api.Orchestrator
import org.rooftop.netx.api.OrchestratorFactory
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import java.util.*

@Service
class CreateGuildFacade(
private val guildService: GuildService,
private val identityApi: IdentityApi,
private val renderApi: RenderApi,
@Value("\${internal.secret}") internalSecret: String,
orchestratorFactory: OrchestratorFactory,
) {

private lateinit var createGuildOrchestrator: Orchestrator<CreateGuildRequest, Unit>

fun createGuild(
token: String,
createGuildRequest: CreateGuildRequest,
) {
createGuildOrchestrator.sagaSync(
createGuildRequest,
context = mapOf("token" to token, IDEMPOTENCY_KEY to UUID.randomUUID().toString()),
).decodeResultOrThrow(Unit::class)
}

init {
createGuildOrchestrator =
orchestratorFactory.create<CreateGuildRequest>("Create guild orchestrator")
.startWithContext(
contextOrchestrate = { context, createGuildRequest ->
val token = context.decodeContext("token", String::class)
val idempotencyKey = context.decodeContext(IDEMPOTENCY_KEY, String::class)

val leader = identityApi.getUserByToken(token)
require(leader.points.toInt() >= CREATE_GUILD_COST) {
"Cannot create guild cause not enough points. points: \"${leader.points}\""
}

identityApi.decreasePoint(
token = token,
internalSecret = internalSecret,
idempotencyKey = idempotencyKey,
point = CREATE_GUILD_COST.toString(),
)
createGuildRequest
},
contextRollback = { context, _ ->
val token = context.decodeContext("token", String::class)
val idempotencyKey = context.decodeContext(IDEMPOTENCY_KEY, String::class)

identityApi.increasePoint(
token = token,
internalSecret = internalSecret,
idempotencyKey = idempotencyKey,
point = CREATE_GUILD_COST.toString(),
)
}
)
.commitWithContext(
contextOrchestrate = { context, createGuildRequest ->
val token = context.decodeContext("token", String::class)

val leader = identityApi.getUserByToken(token)
val renderUser =
renderApi.getUserByName(leader.username)


val createLeaderRequest = CreateLeaderRequest(
userId = leader.id.toLong(),
name = leader.username,
personaId = renderUser.personas.firstOrNull { it.id == createGuildRequest.personaId }?.id?.toLong()
?: throw IllegalArgumentException("Cannot find persona by id \"${createGuildRequest.personaId}\""),
contributions = renderUser.totalContributions.toLong(),
personaType = renderUser.personas.find { it.id == createGuildRequest.personaId }!!.type,
)

guildService.createGuild(
title = createGuildRequest.title,
body = createGuildRequest.body,
guildIcon = createGuildRequest.guildIcon,
farmType = createGuildRequest.farmType,
autoJoin = createGuildRequest.autoJoin,
createLeaderRequest = createLeaderRequest,
)
}
)
}

private companion object {
private const val IDEMPOTENCY_KEY = "IDEMPOTENCY_KEY"
private const val CREATE_GUILD_COST = 30_000
}
}
17 changes: 17 additions & 0 deletions src/main/kotlin/org/gitanimals/guild/app/DenyJoinGuildFacade.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.gitanimals.guild.app

import org.gitanimals.guild.domain.GuildService
import org.springframework.stereotype.Service

@Service
class DenyJoinGuildFacade(
private val identityApi: IdentityApi,
private val guildService: GuildService,
) {

fun denyJoin(token: String, guildId: Long, denyUserId: Long) {
val user = identityApi.getUserByToken(token)

guildService.denyJoin(denierId = user.id.toLong(), guildId = guildId, denyUserId = denyUserId)
}
}
18 changes: 18 additions & 0 deletions src/main/kotlin/org/gitanimals/guild/app/GetJoinedGuildFacade.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.gitanimals.guild.app

import org.gitanimals.guild.domain.Guild
import org.gitanimals.guild.domain.GuildService
import org.springframework.stereotype.Service

@Service
class GetJoinedGuildFacade(
private val identityApi: IdentityApi,
private val guildService: GuildService,
) {

fun getJoinedGuilds(token: String): List<Guild> {
val user = identityApi.getUserByToken(token)

return guildService.findAllGuildByUserId(user.id.toLong())
}
}
40 changes: 40 additions & 0 deletions src/main/kotlin/org/gitanimals/guild/app/IdentityApi.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.gitanimals.guild.app

import org.springframework.http.HttpHeaders
import org.springframework.web.bind.annotation.RequestHeader
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.service.annotation.GetExchange
import org.springframework.web.service.annotation.PostExchange

interface IdentityApi {

@GetExchange("/users")
fun getUserByToken(@RequestHeader(HttpHeaders.AUTHORIZATION) token: String): UserResponse

@PostExchange("/internals/users/points/decreases")
fun decreasePoint(
@RequestHeader(HttpHeaders.AUTHORIZATION) token: String,
@RequestHeader(INTERNAL_SECRET_KEY) internalSecret: String,
@RequestParam("idempotency-key") idempotencyKey: String,
@RequestParam("point") point: String,
)

@PostExchange("/internals/users/points/increases")
fun increasePoint(
@RequestHeader(HttpHeaders.AUTHORIZATION) token: String,
@RequestHeader(INTERNAL_SECRET_KEY) internalSecret: String,
@RequestParam("idempotency-key") idempotencyKey: String,
@RequestParam("point") point: String,
)

data class UserResponse(
val id: String,
val username: String,
val points: String,
val profileImage: String,
)

private companion object {
private const val INTERNAL_SECRET_KEY = "Internal-Secret"
}
}
91 changes: 91 additions & 0 deletions src/main/kotlin/org/gitanimals/guild/app/JoinGuildFacade.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package org.gitanimals.guild.app

import org.gitanimals.guild.app.event.InboxInputEvent
import org.gitanimals.guild.domain.Guild
import org.gitanimals.guild.domain.GuildService
import org.rooftop.netx.api.SagaManager
import org.springframework.stereotype.Service

@Service
class JoinGuildFacade(
private val renderApi: RenderApi,
private val identityApi: IdentityApi,
private val guildService: GuildService,
private val sagaManager: SagaManager,
) {

fun joinGuild(
token: String,
guildId: Long,
memberPersonaId: Long,
) {
val member = identityApi.getUserByToken(token)
val renderInfo = renderApi.getUserByName(member.username)

require(memberPersonaId in renderInfo.personas.map { it.id.toLong() }) {
"Cannot join guild cause user does not have request member persona id. personaId: \"$memberPersonaId\""
}

guildService.joinGuild(
guildId = guildId,
memberUserId = member.id.toLong(),
memberName = member.username,
memberPersonaId = memberPersonaId,
memberContributions = renderInfo.totalContributions.toLong(),
memberPersonaType = renderInfo.personas.find { it.id.toLong() == memberPersonaId }!!.type,
)

val guild = guildService.getGuildById(guildId)
if (guild.isAutoJoin()) {
publishNewUserJoinEvents(guild, member)
return
}

publicGuildJoinRequest(guild, member)
publishSentJoinRequest(guild, member)
}

private fun publishNewUserJoinEvents(
guild: Guild,
member: IdentityApi.UserResponse,
) {
guild.getMembers()
.filter { it.userId != member.id.toLong() }
.forEach {
sagaManager.startSync(
InboxInputEvent.newUserJoined(
userId = it.userId,
newUserImage = member.profileImage,
newUserName = member.username,
guildTitle = guild.getTitle(),
)
)
}
}

private fun publicGuildJoinRequest(
guild: Guild,
member: IdentityApi.UserResponse
) {
sagaManager.startSync(
InboxInputEvent.guildJoinRequest(
userId = guild.getLeaderId(),
newUserImage = member.profileImage,
newUserName = member.username,
guildTitle = guild.getTitle(),
)
)
}

private fun publishSentJoinRequest(
guild: Guild,
member: IdentityApi.UserResponse,
) {
sagaManager.startSync(
InboxInputEvent.sentJoinRequest(
userId = member.id.toLong(),
guildTitle = guild.getTitle(),
)
)
}
}
21 changes: 21 additions & 0 deletions src/main/kotlin/org/gitanimals/guild/app/KickGuildFacade.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.gitanimals.guild.app

import org.gitanimals.guild.domain.GuildService
import org.springframework.stereotype.Service

@Service
class KickGuildFacade(
private val identityApi: IdentityApi,
private val guildService: GuildService,
) {

fun kickMember(token: String, guildId: Long, kickUserId: Long) {
val user = identityApi.getUserByToken(token)

guildService.kickMember(
kickerId = user.id.toLong(),
guildId = guildId,
kickUserId = kickUserId,
)
}
}
17 changes: 17 additions & 0 deletions src/main/kotlin/org/gitanimals/guild/app/LeaveGuildFacade.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.gitanimals.guild.app

import org.gitanimals.guild.domain.GuildService
import org.springframework.stereotype.Component

@Component
class LeaveGuildFacade(
private val identityApi: IdentityApi,
private val guildService: GuildService,
) {

fun leave(token: String, guildId: Long) {
val user = identityApi.getUserByToken(token)

guildService.leave(guildId, user.id.toLong())
}
}
Loading

0 comments on commit 705f52f

Please sign in to comment.