You've already forked RekomenciMobile
feat: updated DTO
This commit is contained in:
+27
-3
@@ -2,7 +2,7 @@
|
|||||||
"formatVersion": 1,
|
"formatVersion": 1,
|
||||||
"database": {
|
"database": {
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"identityHash": "3e896e9a3d3b2f61149f8c0fde7e5964",
|
"identityHash": "b16cf19ddaafa74ea796a48650e53014",
|
||||||
"entities": [
|
"entities": [
|
||||||
{
|
{
|
||||||
"tableName": "users",
|
"tableName": "users",
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tableName": "resumes",
|
"tableName": "resumes",
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `experience_type` TEXT NOT NULL, `about_me` TEXT NOT NULL, `key_skills` TEXT NOT NULL, `position` TEXT NOT NULL, `from_salary` INTEGER, `to_salary` INTEGER, `recommended_skills` TEXT NOT NULL, PRIMARY KEY(`id`))",
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `experience_type` TEXT NOT NULL, `about_me` TEXT NOT NULL, `key_skills` TEXT NOT NULL, `position` TEXT NOT NULL, `from_salary` INTEGER, `to_salary` INTEGER, `recommended_skills` TEXT NOT NULL, `city` TEXT NOT NULL, `experience` TEXT NOT NULL, `education` TEXT NOT NULL, `projects` TEXT NOT NULL, PRIMARY KEY(`id`))",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"fieldPath": "id",
|
"fieldPath": "id",
|
||||||
@@ -102,6 +102,30 @@
|
|||||||
"columnName": "recommended_skills",
|
"columnName": "recommended_skills",
|
||||||
"affinity": "TEXT",
|
"affinity": "TEXT",
|
||||||
"notNull": true
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "city",
|
||||||
|
"columnName": "city",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "experience",
|
||||||
|
"columnName": "experience",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "education",
|
||||||
|
"columnName": "education",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "projects",
|
||||||
|
"columnName": "projects",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"primaryKey": {
|
"primaryKey": {
|
||||||
@@ -114,7 +138,7 @@
|
|||||||
],
|
],
|
||||||
"setupQueries": [
|
"setupQueries": [
|
||||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '3e896e9a3d3b2f61149f8c0fde7e5964')"
|
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'b16cf19ddaafa74ea796a48650e53014')"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,9 +2,11 @@ package com.prodhack.moscow2025.data.data_providers.local_db
|
|||||||
|
|
||||||
import androidx.room.Database
|
import androidx.room.Database
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
|
import androidx.room.TypeConverters
|
||||||
import com.prodhack.moscow2025.data.data_providers.local_db.dao.CleanUpDao
|
import com.prodhack.moscow2025.data.data_providers.local_db.dao.CleanUpDao
|
||||||
import com.prodhack.moscow2025.data.data_providers.local_db.dao.ResumeDao
|
import com.prodhack.moscow2025.data.data_providers.local_db.dao.ResumeDao
|
||||||
import com.prodhack.moscow2025.data.data_providers.local_db.dao.UserDao
|
import com.prodhack.moscow2025.data.data_providers.local_db.dao.UserDao
|
||||||
|
import com.prodhack.moscow2025.data.data_providers.local_db.entities.JsonTypeConverters
|
||||||
import com.prodhack.moscow2025.data.data_providers.local_db.entities.ResumeEntity
|
import com.prodhack.moscow2025.data.data_providers.local_db.entities.ResumeEntity
|
||||||
import com.prodhack.moscow2025.data.data_providers.local_db.entities.UserEntity
|
import com.prodhack.moscow2025.data.data_providers.local_db.entities.UserEntity
|
||||||
|
|
||||||
@@ -13,6 +15,7 @@ import com.prodhack.moscow2025.data.data_providers.local_db.entities.UserEntity
|
|||||||
version = 1,
|
version = 1,
|
||||||
exportSchema = true
|
exportSchema = true
|
||||||
)
|
)
|
||||||
|
@TypeConverters(JsonTypeConverters::class)
|
||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
abstract fun userDao(): UserDao
|
abstract fun userDao(): UserDao
|
||||||
|
|
||||||
|
|||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
package com.prodhack.moscow2025.data.data_providers.local_db.entities
|
||||||
|
|
||||||
|
import androidx.room.TypeConverter
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.google.gson.reflect.TypeToken
|
||||||
|
import com.prodhack.moscow2025.domain.models.Education
|
||||||
|
import com.prodhack.moscow2025.domain.models.Project
|
||||||
|
import com.prodhack.moscow2025.domain.models.WorkExperience
|
||||||
|
|
||||||
|
object JsonTypeConverters {
|
||||||
|
|
||||||
|
private val gson = Gson()
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun fromWorkExperienceList(value: List<WorkExperience>): String {
|
||||||
|
val type = object : TypeToken<List<WorkExperience>>() {}.type
|
||||||
|
return gson.toJson(value, type)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun toWorkExperienceList(value: String): List<WorkExperience> {
|
||||||
|
val type = object : TypeToken<List<WorkExperience>>() {}.type
|
||||||
|
return gson.fromJson(value, type)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun fromEducationList(value: List<Education>): String {
|
||||||
|
val type = object : TypeToken<List<Education>>() {}.type
|
||||||
|
return gson.toJson(value, type)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun toEducationList(value: String): List<Education> {
|
||||||
|
val type = object : TypeToken<List<Education>>() {}.type
|
||||||
|
return gson.fromJson(value, type)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun fromProjectList(value: List<Project>): String {
|
||||||
|
val type = object : TypeToken<List<Project>>() {}.type
|
||||||
|
return gson.toJson(value, type)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun toProjectList(value: String): List<Project> {
|
||||||
|
val type = object : TypeToken<List<Project>>() {}.type
|
||||||
|
return gson.fromJson(value, type)
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
-3
@@ -5,7 +5,6 @@ import androidx.room.Entity
|
|||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import com.prodhack.moscow2025.domain.models.ExperienceType
|
import com.prodhack.moscow2025.domain.models.ExperienceType
|
||||||
import com.prodhack.moscow2025.domain.models.ResumeModel
|
import com.prodhack.moscow2025.domain.models.ResumeModel
|
||||||
import kotlin.math.exp
|
|
||||||
|
|
||||||
@Entity(tableName = "resumes")
|
@Entity(tableName = "resumes")
|
||||||
data class ResumeEntity(
|
data class ResumeEntity(
|
||||||
@@ -23,7 +22,11 @@ data class ResumeEntity(
|
|||||||
@ColumnInfo("to_salary")
|
@ColumnInfo("to_salary")
|
||||||
val toSalary: Int?,
|
val toSalary: Int?,
|
||||||
@ColumnInfo("recommended_skills")
|
@ColumnInfo("recommended_skills")
|
||||||
val recommendedSkills: String
|
val recommendedSkills: String,
|
||||||
|
val city: String,
|
||||||
|
val experience: String, // Store as JSON string, requires TypeConverter
|
||||||
|
val education: String, // Store as JSON string, requires TypeConverter
|
||||||
|
val projects: String // Store as JSON string, requires TypeConverter
|
||||||
) {
|
) {
|
||||||
fun mapToDomain(): ResumeModel = ResumeModel(
|
fun mapToDomain(): ResumeModel = ResumeModel(
|
||||||
id = id,
|
id = id,
|
||||||
@@ -32,6 +35,10 @@ data class ResumeEntity(
|
|||||||
experienceType = ExperienceType.valueOf(experienceType),
|
experienceType = ExperienceType.valueOf(experienceType),
|
||||||
skills = keySkills.split("|"),
|
skills = keySkills.split("|"),
|
||||||
prediction = Pair(fromSalary, toSalary),
|
prediction = Pair(fromSalary, toSalary),
|
||||||
recommendedSkills = recommendedSkills.split("|")
|
recommendedSkills = recommendedSkills.split("|"),
|
||||||
|
city = city,
|
||||||
|
experience = JsonTypeConverters.toWorkExperienceList(experience),
|
||||||
|
education = JsonTypeConverters.toEducationList(education),
|
||||||
|
projects = JsonTypeConverters.toProjectList(projects)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
package com.prodhack.moscow2025.data.dto
|
package com.prodhack.moscow2025.data.dto
|
||||||
|
|
||||||
|
import com.prodhack.moscow2025.data.data_providers.local_db.entities.JsonTypeConverters
|
||||||
import com.prodhack.moscow2025.data.data_providers.local_db.entities.ResumeEntity
|
import com.prodhack.moscow2025.data.data_providers.local_db.entities.ResumeEntity
|
||||||
|
import com.prodhack.moscow2025.domain.models.Education
|
||||||
|
import com.prodhack.moscow2025.domain.models.EducationGrades
|
||||||
import com.prodhack.moscow2025.domain.models.ExperienceType
|
import com.prodhack.moscow2025.domain.models.ExperienceType
|
||||||
import com.prodhack.moscow2025.domain.models.ResumeCreationModel
|
import com.prodhack.moscow2025.domain.models.Project
|
||||||
import com.prodhack.moscow2025.domain.models.ResumeModel
|
import com.prodhack.moscow2025.domain.models.ResumeModel
|
||||||
|
import com.prodhack.moscow2025.domain.models.WorkExperience
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@@ -51,6 +55,10 @@ data class ResumeDTO(
|
|||||||
@SerialName("key_skills")
|
@SerialName("key_skills")
|
||||||
val keySkills: List<String>,
|
val keySkills: List<String>,
|
||||||
val position: String,
|
val position: String,
|
||||||
|
val city: String,
|
||||||
|
val experience: List<ExperienceDTO>,
|
||||||
|
val education: List<EducationDTO>,
|
||||||
|
val project: List<ProjectDTO>,
|
||||||
val prediction: PredictionDTO
|
val prediction: PredictionDTO
|
||||||
) {
|
) {
|
||||||
fun mapToDomain(): ResumeModel = ResumeModel(
|
fun mapToDomain(): ResumeModel = ResumeModel(
|
||||||
@@ -63,7 +71,11 @@ data class ResumeDTO(
|
|||||||
prediction.fromSalary.toIntOrNull(),
|
prediction.fromSalary.toIntOrNull(),
|
||||||
prediction.toSalary.toIntOrNull()
|
prediction.toSalary.toIntOrNull()
|
||||||
),
|
),
|
||||||
recommendedSkills = prediction.recommendedSkills
|
recommendedSkills = prediction.recommendedSkills,
|
||||||
|
city = city,
|
||||||
|
experience = experience.map { it.mapToDomain() },
|
||||||
|
education = education.map { it.mapToDomain() },
|
||||||
|
projects = project.map { it.mapToDomain() }
|
||||||
)
|
)
|
||||||
|
|
||||||
fun mapToDB(): ResumeEntity = ResumeEntity(
|
fun mapToDB(): ResumeEntity = ResumeEntity(
|
||||||
@@ -74,25 +86,97 @@ data class ResumeDTO(
|
|||||||
fromSalary = prediction.fromSalary.toIntOrNull(),
|
fromSalary = prediction.fromSalary.toIntOrNull(),
|
||||||
toSalary = prediction.toSalary.toIntOrNull(),
|
toSalary = prediction.toSalary.toIntOrNull(),
|
||||||
recommendedSkills = prediction.recommendedSkills.joinToString("|"),
|
recommendedSkills = prediction.recommendedSkills.joinToString("|"),
|
||||||
experienceType = experienceType.mapToDomain().name
|
experienceType = experienceType.mapToDomain().name,
|
||||||
|
city = city,
|
||||||
|
experience = JsonTypeConverters.fromWorkExperienceList(experience.map { it.mapToDomain() }),
|
||||||
|
education = JsonTypeConverters.fromEducationList(education.map { it.mapToDomain() }),
|
||||||
|
projects = JsonTypeConverters.fromProjectList(project.map { it.mapToDomain() }),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ExperienceDTO(
|
||||||
|
val place: String,
|
||||||
|
val description: String,
|
||||||
|
@SerialName("month_duration")
|
||||||
|
val monthDuration: Int,
|
||||||
|
) {
|
||||||
|
fun mapToDomain(): WorkExperience = WorkExperience(
|
||||||
|
place = place,
|
||||||
|
description = description,
|
||||||
|
monthDuration = monthDuration
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class EducationDTO(
|
||||||
|
val place: String,
|
||||||
|
val grade: EducationGradesDTO,
|
||||||
|
val specialization: String,
|
||||||
|
val description: String
|
||||||
|
) {
|
||||||
|
fun mapToDomain(): Education = Education(
|
||||||
|
place = place,
|
||||||
|
grade = grade.mapToDomain(),
|
||||||
|
specialization = specialization,
|
||||||
|
description = description
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
enum class EducationGradesDTO {
|
||||||
|
@SerialName("common")
|
||||||
|
Common,
|
||||||
|
|
||||||
|
@SerialName("middle")
|
||||||
|
Middle,
|
||||||
|
|
||||||
|
@SerialName("middle_spec")
|
||||||
|
MiddleSpec,
|
||||||
|
|
||||||
|
@SerialName("high_not_finished")
|
||||||
|
HighNotFinished,
|
||||||
|
|
||||||
|
@SerialName("high")
|
||||||
|
High,
|
||||||
|
|
||||||
|
@SerialName("additional")
|
||||||
|
Additional;
|
||||||
|
|
||||||
|
fun mapToDomain(): EducationGrades = when (this) {
|
||||||
|
Common -> EducationGrades.Common
|
||||||
|
Middle -> EducationGrades.Middle
|
||||||
|
MiddleSpec -> EducationGrades.MiddleSpec
|
||||||
|
HighNotFinished -> EducationGrades.HighNotFinished
|
||||||
|
High -> EducationGrades.High
|
||||||
|
Additional -> EducationGrades.Additional
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ProjectDTO(
|
||||||
|
val name: String,
|
||||||
|
val description: String
|
||||||
|
) {
|
||||||
|
fun mapToDomain(): Project = Project(
|
||||||
|
name = name,
|
||||||
|
description = description
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class ResumeCreateDTO(
|
data class ResumeCreateDTO(
|
||||||
@SerialName("about_me")
|
|
||||||
val aboutMe: String,
|
|
||||||
@SerialName("experience_type")
|
@SerialName("experience_type")
|
||||||
val experienceType: ExperienceTypeDTO,
|
val experienceType: ExperienceTypeDTO,
|
||||||
|
@SerialName("about_me")
|
||||||
|
val aboutMe: String,
|
||||||
|
@SerialName("key_skills")
|
||||||
val keySkills: List<String>,
|
val keySkills: List<String>,
|
||||||
val position: String
|
val position: String,
|
||||||
)
|
val city: String,
|
||||||
|
val experience: List<ExperienceDTO>,
|
||||||
fun ResumeCreationModel.mapToData(): ResumeCreateDTO = ResumeCreateDTO(
|
val education: List<EducationDTO>,
|
||||||
aboutMe = about,
|
val project: List<ProjectDTO>,
|
||||||
experienceType = experienceType.mapToData(),
|
|
||||||
keySkills = skills,
|
|
||||||
position = position
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
|||||||
@@ -5,7 +5,11 @@ data class ResumeModel(
|
|||||||
val position: String,
|
val position: String,
|
||||||
val about: String,
|
val about: String,
|
||||||
val skills: List<String>,
|
val skills: List<String>,
|
||||||
|
val city: String,
|
||||||
val experienceType: ExperienceType,
|
val experienceType: ExperienceType,
|
||||||
|
val experience: List<WorkExperience>,
|
||||||
|
val education: List<Education>,
|
||||||
|
val projects: List<Project>,
|
||||||
val prediction: Pair<Int?, Int?>,
|
val prediction: Pair<Int?, Int?>,
|
||||||
val recommendedSkills: List<String>
|
val recommendedSkills: List<String>
|
||||||
)
|
)
|
||||||
@@ -14,7 +18,38 @@ data class ResumeCreationModel(
|
|||||||
val position: String,
|
val position: String,
|
||||||
val about: String,
|
val about: String,
|
||||||
val skills: List<String>,
|
val skills: List<String>,
|
||||||
val experienceType: ExperienceType
|
val city: String?,
|
||||||
|
val experienceType: ExperienceType,
|
||||||
|
val experience: List<WorkExperience>,
|
||||||
|
val education: List<Education>,
|
||||||
|
val projects: List<Project>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class WorkExperience(
|
||||||
|
val place: String,
|
||||||
|
val description: String,
|
||||||
|
val monthDuration: Int
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Education(
|
||||||
|
val place: String,
|
||||||
|
val grade: EducationGrades,
|
||||||
|
val specialization: String,
|
||||||
|
val description: String
|
||||||
|
)
|
||||||
|
|
||||||
|
enum class EducationGrades {
|
||||||
|
Common,
|
||||||
|
Middle,
|
||||||
|
MiddleSpec,
|
||||||
|
HighNotFinished,
|
||||||
|
High,
|
||||||
|
Additional
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Project(
|
||||||
|
val name: String,
|
||||||
|
val description: String
|
||||||
)
|
)
|
||||||
|
|
||||||
enum class ExperienceType {
|
enum class ExperienceType {
|
||||||
|
|||||||
+3
-2
@@ -7,6 +7,7 @@ import org.koin.core.annotation.Single
|
|||||||
@Single
|
@Single
|
||||||
class CreateResumeUseCase(
|
class CreateResumeUseCase(
|
||||||
private val resumeRepository: ResumeRepository
|
private val resumeRepository: ResumeRepository
|
||||||
){
|
) {
|
||||||
suspend operator fun invoke(resumeForm: ResumeCreationModel): Result<String> = resumeRepository.createResume(resumeForm)
|
suspend operator fun invoke(resumeForm: ResumeCreationModel): Result<String> =
|
||||||
|
resumeRepository.createResume(resumeForm)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -30,6 +30,10 @@ class LoadResumeListUseCase(private val resumeRepository: ResumeRepository) {
|
|||||||
"Ktor"
|
"Ktor"
|
||||||
),
|
),
|
||||||
experienceType = ExperienceType.Between3And6,
|
experienceType = ExperienceType.Between3And6,
|
||||||
|
city = "Moscow",
|
||||||
|
experience = listOf(),
|
||||||
|
education = listOf(),
|
||||||
|
projects = listOf(),
|
||||||
prediction = Pair(200000, 230000),
|
prediction = Pair(200000, 230000),
|
||||||
recommendedSkills = listOf("KMP")
|
recommendedSkills = listOf("KMP")
|
||||||
)
|
)
|
||||||
|
|||||||
+1
-1
@@ -154,7 +154,7 @@ fun CreateResumeScreen(
|
|||||||
Spacer(modifier = Modifier.height(Paddings.large))
|
Spacer(modifier = Modifier.height(Paddings.large))
|
||||||
|
|
||||||
BigButton(
|
BigButton(
|
||||||
onClick = {},
|
onClick = viewModel::submit,
|
||||||
buttonText = "Узнать свою ЗП",
|
buttonText = "Узнать свою ЗП",
|
||||||
isLoading = viewModel.resumeFillState.collectAsState().value.isLoading
|
isLoading = viewModel.resumeFillState.collectAsState().value.isLoading
|
||||||
)
|
)
|
||||||
|
|||||||
+5
-1
@@ -138,7 +138,11 @@ class CreateResumeViewModel(
|
|||||||
position = position,
|
position = position,
|
||||||
about = about,
|
about = about,
|
||||||
skills = keySkills.toList(),
|
skills = keySkills.toList(),
|
||||||
experienceType = experience!!.mapToDomain()
|
experienceType = experience!!.mapToDomain(),
|
||||||
|
city = null,
|
||||||
|
experience = emptyList(),
|
||||||
|
education = emptyList(),
|
||||||
|
projects = emptyList()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user