Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions app/models/daos/slick/DBTableDefinitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import java.util.UUID

object DBTableDefinitions {

case class DBUser (userId: String, username: String, email: String )
case class DBUser(userId: String, username: String, email: String, tutorialCompleted: Boolean = false)


class UserTable(tag: Tag) extends Table[DBUser](tag, "sidewalk_user") {
def userId = column[String]("user_id", O.PrimaryKey)
def username = column[String]("username")
def email = column[String]("email")
def * = (userId, username, email) <> (DBUser.tupled, DBUser.unapply)
def tutorialCompleted = column[Boolean]("tutorial_completed")
def * = (userId, username, email, tutorialCompleted) <> (DBUser.tupled, DBUser.unapply)
}

case class DBLoginInfo (id: Option[Long], providerID: String, providerKey: String )
Expand Down
37 changes: 29 additions & 8 deletions app/models/mission/MissionTable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,14 @@ object MissionTable {
* Check if the user has completed onboarding.
*/
def hasCompletedAuditOnboarding(userId: UUID): Boolean = db.withSession { implicit session =>
selectCompletedMissions(userId, includeOnboarding = true, includeSkipped = true)
.exists(_.missionTypeId == MissionTypeTable.missionTypeToId("auditOnboarding"))
users.filter(_.userId === userId.toString).map(_.tutorialCompleted).first
}

/**
* Updates the user's profile to mark the tutorial as completed.
*/
def markTutorialCompleted(userId: UUID): Int = db.withSession { implicit session =>
users.filter(_.userId === userId.toString).map(_.tutorialCompleted).update(true)
}

/**
Expand Down Expand Up @@ -613,17 +619,32 @@ object MissionTable {
}

/**
* Marks the specified mission as complete, filling in mission_end timestamp.
*
* NOTE only call from queryMissionTable or queryMissionTableValidationMissions funcs to prevent race conditions.
*
* @return Int number of rows updated (should always be 1).
*/
* Marks the specified mission as complete, filling in mission_end timestamp.
* If the mission is an audit onboarding mission, also marks the tutorial as completed
* in the user's profile to prevent it from appearing again in any city.
*
* NOTE only call from queryMissionTable or queryMissionTableValidationMissions funcs to prevent race conditions.
*
* @return Int number of rows updated (should always be 1).
*/
def updateComplete(missionId: Int): Int = db.withSession { implicit session =>
val now: Timestamp = new Timestamp(Instant.now.toEpochMilli)
val missionToUpdate = for { m <- missions if m.missionId === missionId } yield (m.completed, m.missionEnd)
val rowsUpdated: Int = missionToUpdate.update((true, now))
if (rowsUpdated == 0) Logger.error("Tried to mark a mission as complete, but no mission exists with that ID.")

try {
// Check if this is an audit onboarding mission and mark tutorial as completed if it is
val missionType = getMissionType(missionId)
if (missionType.exists(_ == "auditOnboarding")) {
val userId = missions.filter(_.missionId === missionId).map(_.userId).first
markTutorialCompleted(UUID.fromString(userId))
}
} catch {
case e: Exception =>
Logger.error(s"Error updating tutorial completion status: ${e.getMessage}")
}

rowsUpdated
}

Expand Down
16 changes: 16 additions & 0 deletions conf/evolutions/default/269.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# --- !Ups
ALTER TABLE sidewalk_user ADD COLUMN IF NOT EXISTS tutorial_completed BOOLEAN NOT NULL DEFAULT FALSE;

UPDATE sidewalk_user AS su
SET tutorial_completed = TRUE
WHERE EXISTS (
SELECT 1
FROM mission AS m
JOIN mission_type AS mt ON m.mission_type_id = mt.mission_type_id
WHERE m.user_id = su.user_id
AND mt.mission_type = 'auditOnboarding'
AND m.completed = TRUE
);

# --- !Downs
ALTER TABLE sidewalk_user DROP COLUMN IF EXISTS tutorial_completed;