Merge remote-tracking branch 'refs/remotes/origin/main'

sync_v2
Raz 7 months ago
commit db20896f10
  1. 16
      PadelClub/Data/Gen/BaseTournament.swift
  2. 6
      PadelClub/Data/Gen/Tournament.json
  3. 27
      PadelClub/Data/Gen/generator.py
  4. 5
      PadelClub/Utils/Patcher.swift
  5. 6
      PadelClubTests/ServerDataTests.swift

@ -195,6 +195,8 @@ class BaseTournament: SyncedModelObject, SyncedStorable {
} }
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case isCanceled = "isCanceled"
case payment = "payment"
case _id = "id" case _id = "id"
case _event = "event" case _event = "event"
case _name = "name" case _name = "name"
@ -221,10 +223,10 @@ class BaseTournament: SyncedModelObject, SyncedStorable {
case _qualifiedPerGroupStage = "qualifiedPerGroupStage" case _qualifiedPerGroupStage = "qualifiedPerGroupStage"
case _teamsPerGroupStage = "teamsPerGroupStage" case _teamsPerGroupStage = "teamsPerGroupStage"
case _entryFee = "entryFee" case _entryFee = "entryFee"
case _payment = "payment" case _payment = "globalId"
case _additionalEstimationDuration = "additionalEstimationDuration" case _additionalEstimationDuration = "additionalEstimationDuration"
case _isDeleted = "isDeleted" case _isDeleted = "isDeleted"
case _isCanceled = "isCanceled" case _isCanceled = "localId"
case _publishTeams = "publishTeams" case _publishTeams = "publishTeams"
case _publishSummons = "publishSummons" case _publishSummons = "publishSummons"
case _publishGroupStages = "publishGroupStages" case _publishGroupStages = "publishGroupStages"
@ -257,7 +259,10 @@ class BaseTournament: SyncedModelObject, SyncedStorable {
} }
private static func _decodePayment(container: KeyedDecodingContainer<CodingKeys>) throws -> TournamentPayment? { private static func _decodePayment(container: KeyedDecodingContainer<CodingKeys>) throws -> TournamentPayment? {
let data = try container.decodeIfPresent(Data.self, forKey: ._payment) var data = try container.decodeIfPresent(Data.self, forKey: ._payment)
if data == nil {
data = try container.decodeIfPresent(Data.self, forKey: .payment)
}
if let data { if let data {
do { do {
@ -290,7 +295,10 @@ class BaseTournament: SyncedModelObject, SyncedStorable {
} }
} }
private static func _decodeIscanceled(container: KeyedDecodingContainer<CodingKeys>) throws -> Bool { private static func _decodeIscanceled(container: KeyedDecodingContainer<CodingKeys>) throws -> Bool {
let data = try container.decodeIfPresent(Data.self, forKey: ._isCanceled) var data = try container.decodeIfPresent(Data.self, forKey: ._isCanceled)
if data == nil {
data = try container.decodeIfPresent(Data.self, forKey: .isCanceled)
}
if let data { if let data {
do { do {
let decoded: String = try data.decryptData(pass: CryptoKey.pass.rawValue) let decoded: String = try data.decryptData(pass: CryptoKey.pass.rawValue)

@ -137,7 +137,8 @@
"type": "TournamentPayment", "type": "TournamentPayment",
"optional": true, "optional": true,
"defaultValue": "nil", "defaultValue": "nil",
"encryption": "tournament_payment" "encryption": "tournament_payment",
"codingKey": "globalId"
}, },
{ {
"name": "additionalEstimationDuration", "name": "additionalEstimationDuration",
@ -153,7 +154,8 @@
"name": "isCanceled", "name": "isCanceled",
"type": "Bool", "type": "Bool",
"defaultValue": "false", "defaultValue": "false",
"encryption": "tournament_iscanceled" "encryption": "tournament_iscanceled",
"codingKey": "localId"
}, },
{ {
"name": "publishTeams", "name": "publishTeams",

@ -61,7 +61,7 @@ class SwiftModelGenerator:
lines.append("") lines.append("")
# CodingKeys # CodingKeys
lines.extend(self._generate_coding_keys(properties, is_observable, is_sync)) lines.extend(self._generate_coding_keys(model_name, properties, is_observable))
lines.append("") lines.append("")
# Encryption methods # Encryption methods
@ -166,13 +166,22 @@ class SwiftModelGenerator:
lines.extend([" }", ""]) # Close the method and add a blank line lines.extend([" }", ""]) # Close the method and add a blank line
return lines return lines
def _generate_coding_keys(self, properties: List[Dict[str, Any]], is_observable: bool, is_sync: bool = False) -> List[str]: def _generate_coding_keys(self, model_name: str, properties: List[Dict[str, Any]], is_observable: bool) -> List[str]:
lines = [" enum CodingKeys: String, CodingKey {"] lines = [" enum CodingKeys: String, CodingKey {"]
if model_name == 'Tournament':
lines.append(" case isCanceled = \"isCanceled\"")
lines.append(" case payment = \"payment\"")
for prop in properties: for prop in properties:
name = prop['name'] name = prop['name']
# Add underscore prefix to case name if observable, but keep the string value without underscore # Add underscore prefix to case name if observable
case_name = f"_{name}" if is_observable else name case_name = f"_{name}" if is_observable else name
lines.append(f" case {case_name} = \"{name}\"")
# Use custom codingKey if provided, otherwise use the property name
coding_key_value = prop.get("codingKey", name)
lines.append(f" case {case_name} = \"{coding_key_value}\"")
lines.append(" }") lines.append(" }")
return lines return lines
@ -186,7 +195,10 @@ class SwiftModelGenerator:
if enc_type == "tournament_payment": if enc_type == "tournament_payment":
lines.extend([ lines.extend([
f" private static func _decode{name.capitalize()}(container: KeyedDecodingContainer<CodingKeys>) throws -> TournamentPayment? {{", f" private static func _decode{name.capitalize()}(container: KeyedDecodingContainer<CodingKeys>) throws -> TournamentPayment? {{",
f" let data = try container.decodeIfPresent(Data.self, forKey: ._{name})", f" var data = try container.decodeIfPresent(Data.self, forKey: ._{name})",
" if data == nil {",
" data = try container.decodeIfPresent(Data.self, forKey: .payment)",
" }",
" ", " ",
" if let data {", " if let data {",
" do {", " do {",
@ -222,7 +234,10 @@ class SwiftModelGenerator:
elif enc_type == "tournament_iscanceled": elif enc_type == "tournament_iscanceled":
lines.extend([ lines.extend([
f" private static func _decode{name.capitalize()}(container: KeyedDecodingContainer<CodingKeys>) throws -> Bool {{", f" private static func _decode{name.capitalize()}(container: KeyedDecodingContainer<CodingKeys>) throws -> Bool {{",
f" let data = try container.decodeIfPresent(Data.self, forKey: ._{name})", f" var data = try container.decodeIfPresent(Data.self, forKey: ._{name})",
" if data == nil {",
" data = try container.decodeIfPresent(Data.self, forKey: .isCanceled)",
" }",
" if let data {", " if let data {",
" do {", " do {",
" let decoded: String = try data.decryptData(pass: CryptoKey.pass.rawValue)", " let decoded: String = try data.decryptData(pass: CryptoKey.pass.rawValue)",

@ -53,6 +53,7 @@ enum PatchError: Error {
enum Patch: String, CaseIterable { enum Patch: String, CaseIterable {
case cleanLogs case cleanLogs
case syncUpgrade case syncUpgrade
case updateTournaments
var id: String { var id: String {
return "padelclub.app.patch.\(self.rawValue)" return "padelclub.app.patch.\(self.rawValue)"
@ -83,6 +84,7 @@ class AutomaticPatcher {
switch patch { switch patch {
case .cleanLogs: self._cleanLogs() case .cleanLogs: self._cleanLogs()
case .syncUpgrade: self._syncUpgrade() case .syncUpgrade: self._syncUpgrade()
case .updateTournaments: self._updateTournaments()
} }
} }
@ -128,4 +130,7 @@ class AutomaticPatcher {
} }
} }
fileprivate static func _updateTournaments() {
DataStore.shared.tournaments.addOrUpdate(contentOfs: DataStore.shared.tournaments)
}
} }

@ -115,8 +115,14 @@ final class ServerDataTests: XCTestCase {
let tournament = Tournament(event: eventId, name: "RG Homme", startDate: Date(), endDate: nil, creationDate: Date(), isPrivate: false, groupStageFormat: MatchFormat.megaTie, roundFormat: MatchFormat.nineGames, loserRoundFormat: MatchFormat.nineGamesDecisivePoint, groupStageSortMode: GroupStageOrderingMode.snake, groupStageCount: 2, rankSourceDate: Date(), dayDuration: 5, teamCount: 3, teamSorting: TeamSortingType.rank, federalCategory: TournamentCategory.mix, federalLevelCategory: TournamentLevel.p1000, federalAgeCategory: FederalTournamentAge.a45, closedRegistrationDate: Date(), groupStageAdditionalQualified: 4, courtCount: 9, prioritizeClubMembers: true, qualifiedPerGroupStage: 1, teamsPerGroupStage: 2, entryFee: 30.0, additionalEstimationDuration: 5, isDeleted: true, publishTeams: true, publishSummons: true, publishGroupStages: true, publishBrackets: true, shouldVerifyBracket: true, shouldVerifyGroupStage: true, hideTeamsWeight: true, publishTournament: true, hidePointsEarned: true, publishRankings: true, loserBracketMode: .manual, initialSeedRound: 8, initialSeedCount: 4, accountIsRequired: false, licenseIsRequired: false, minimumPlayerPerTeam: 3, maximumPlayerPerTeam: 5, information: "Super", umpireCustomMail: "razmig@padelclub.app", umpireCustomContact: "Raz", umpireCustomPhone: "+33681598193", hideUmpireMail: true, hideUmpirePhone: true, disableRankingFederalRuling: true, teamCountLimit: false) let tournament = Tournament(event: eventId, name: "RG Homme", startDate: Date(), endDate: nil, creationDate: Date(), isPrivate: false, groupStageFormat: MatchFormat.megaTie, roundFormat: MatchFormat.nineGames, loserRoundFormat: MatchFormat.nineGamesDecisivePoint, groupStageSortMode: GroupStageOrderingMode.snake, groupStageCount: 2, rankSourceDate: Date(), dayDuration: 5, teamCount: 3, teamSorting: TeamSortingType.rank, federalCategory: TournamentCategory.mix, federalLevelCategory: TournamentLevel.p1000, federalAgeCategory: FederalTournamentAge.a45, closedRegistrationDate: Date(), groupStageAdditionalQualified: 4, courtCount: 9, prioritizeClubMembers: true, qualifiedPerGroupStage: 1, teamsPerGroupStage: 2, entryFee: 30.0, additionalEstimationDuration: 5, isDeleted: true, publishTeams: true, publishSummons: true, publishGroupStages: true, publishBrackets: true, shouldVerifyBracket: true, shouldVerifyGroupStage: true, hideTeamsWeight: true, publishTournament: true, hidePointsEarned: true, publishRankings: true, loserBracketMode: .manual, initialSeedRound: 8, initialSeedCount: 4, accountIsRequired: false, licenseIsRequired: false, minimumPlayerPerTeam: 3, maximumPlayerPerTeam: 5, information: "Super", umpireCustomMail: "razmig@padelclub.app", umpireCustomContact: "Raz", umpireCustomPhone: "+33681598193", hideUmpireMail: true, hideUmpirePhone: true, disableRankingFederalRuling: true, teamCountLimit: false)
tournament.isCanceled = true
tournament.payment = .subscriptionUnit
if let t = try await StoreCenter.main.service().post(tournament) { if let t = try await StoreCenter.main.service().post(tournament) {
assert(t.isCanceled == tournament.isCanceled)
assert(t.payment == tournament.payment)
assert(t.lastUpdate.formatted() == tournament.lastUpdate.formatted()) assert(t.lastUpdate.formatted() == tournament.lastUpdate.formatted())
assert(t.event == tournament.event) assert(t.event == tournament.event)
assert(t.name == tournament.name) assert(t.name == tournament.name)

Loading…
Cancel
Save