Events working
This commit is contained in:
parent
ff8803ba68
commit
8db95e6d40
@ -22160,6 +22160,50 @@ Transform:
|
|||||||
m_CorrespondingSourceObject: {fileID: 4270791331071568, guid: f0bfb58546547264682d6066f7947e72, type: 3}
|
m_CorrespondingSourceObject: {fileID: 4270791331071568, guid: f0bfb58546547264682d6066f7947e72, type: 3}
|
||||||
m_PrefabInstance: {fileID: 71862592}
|
m_PrefabInstance: {fileID: 71862592}
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
--- !u!1 &292487261
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 292487263}
|
||||||
|
- component: {fileID: 292487262}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: SupabaseTestInsert
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!114 &292487262
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 292487261}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 619706b2e2fd4fe4eb36567a686c7da0, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
--- !u!4 &292487263
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 292487261}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: -0.0981338, y: 2.3009996, z: 3.8460662}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!4 &292591182 stripped
|
--- !u!4 &292591182 stripped
|
||||||
Transform:
|
Transform:
|
||||||
m_CorrespondingSourceObject: {fileID: 4940683387464080, guid: 1941338505201ed4b86d0fc32a45bdcc, type: 3}
|
m_CorrespondingSourceObject: {fileID: 4940683387464080, guid: 1941338505201ed4b86d0fc32a45bdcc, type: 3}
|
||||||
@ -154096,6 +154140,65 @@ Transform:
|
|||||||
m_CorrespondingSourceObject: {fileID: 4829453017703304, guid: 07751b6a4092629438c147af65e877b3, type: 3}
|
m_CorrespondingSourceObject: {fileID: 4829453017703304, guid: 07751b6a4092629438c147af65e877b3, type: 3}
|
||||||
m_PrefabInstance: {fileID: 1574431602}
|
m_PrefabInstance: {fileID: 1574431602}
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
--- !u!1 &2143540272
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 2143540275}
|
||||||
|
- component: {fileID: 2143540274}
|
||||||
|
- component: {fileID: 2143540273}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: SupabaseManager
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!114 &2143540273
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2143540272}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 50b27839ecef84443a10112beb860a7a, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
--- !u!114 &2143540274
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2143540272}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: ef01b27a4a6f3724a981d178a963c567, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
supabaseUrl: https://vihjspljbslozbjzxutl.supabase.co
|
||||||
|
supabaseKey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZpaGpzcGxqYnNsb3pianp4dXRsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDk1NDc4OTMsImV4cCI6MjA2NTEyMzg5M30.IYPvShgu5j3NnE5PHn-aFLCBJl1QQaVQvAjzxFt8tlA
|
||||||
|
--- !u!4 &2143540275
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2143540272}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: -0.0981338, y: 2.3009996, z: 3.8460662}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!1001 &2143858061
|
--- !u!1001 &2143858061
|
||||||
PrefabInstance:
|
PrefabInstance:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -160336,3 +160439,5 @@ SceneRoots:
|
|||||||
- {fileID: 401603027}
|
- {fileID: 401603027}
|
||||||
- {fileID: 72663021}
|
- {fileID: 72663021}
|
||||||
- {fileID: 1568526664}
|
- {fileID: 1568526664}
|
||||||
|
- {fileID: 2143540275}
|
||||||
|
- {fileID: 292487263}
|
||||||
|
|||||||
@ -53,6 +53,8 @@ public class BodyLinkHandler : MonoBehaviour, IPointerClickHandler, IPointerExit
|
|||||||
string arabicLog = $"تم الضغط على الرابط '{linkID}' في البريد من '{email.senderName}'";
|
string arabicLog = $"تم الضغط على الرابط '{linkID}' في البريد من '{email.senderName}'";
|
||||||
|
|
||||||
UserActionLogger.Instance?.Log(englishLog, arabicLog);
|
UserActionLogger.Instance?.Log(englishLog, arabicLog);
|
||||||
|
bool isOptimal = !email.isPhishing;
|
||||||
|
SupabaseEventLogger.Instance?.LogDecisionEvent(isOptimal);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@ -54,6 +54,7 @@ public class CharacterMovement : MonoBehaviour
|
|||||||
{
|
{
|
||||||
animator.SetTrigger("StartWalking");
|
animator.SetTrigger("StartWalking");
|
||||||
isStarted = true;
|
isStarted = true;
|
||||||
|
SupabaseEventLogger.Instance?.StartSession();
|
||||||
InstructionManager.Instance?.ShowScreenInstruction("mission_intro");
|
InstructionManager.Instance?.ShowScreenInstruction("mission_intro");
|
||||||
}
|
}
|
||||||
void Update()
|
void Update()
|
||||||
|
|||||||
@ -129,6 +129,14 @@ public class EmailOpenPanel : MonoBehaviour
|
|||||||
SceneOutcomeManager.Instance.Ignored(emailData);
|
SceneOutcomeManager.Instance.Ignored(emailData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SupabaseEventLogger.Instance?.CompleteSessionAndSubmitResult(
|
||||||
|
userId: "user123", // replace with real user ID if available
|
||||||
|
passed: isCorrect,
|
||||||
|
optimal: isCorrect ? 1 : 0,
|
||||||
|
suboptimal: isCorrect ? 0 : 1,
|
||||||
|
scenarioId: "scene_1"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalizeTMP(TextMeshProUGUI tmp, string english, string arabic)
|
void LocalizeTMP(TextMeshProUGUI tmp, string english, string arabic)
|
||||||
|
|||||||
@ -61,6 +61,9 @@ public class MiniQuizManager : MonoBehaviour
|
|||||||
|
|
||||||
// Prepend a ✅ to the selected label
|
// Prepend a ✅ to the selected label
|
||||||
answerLabels[selectedIndex].text = "✅ " + answerLabels[selectedIndex].text;
|
answerLabels[selectedIndex].text = "✅ " + answerLabels[selectedIndex].text;
|
||||||
|
|
||||||
|
bool isCorrect = (selectedIndex == correctIndex);
|
||||||
|
SupabaseEventLogger.Instance?.LogDecisionEvent(isCorrect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
180
Assets/SupabaseEventLogger.cs
Normal file
180
Assets/SupabaseEventLogger.cs
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Supabase; // Make sure SupabaseManager initializes this correctly
|
||||||
|
using Postgrest.Models;
|
||||||
|
using Postgrest.Attributes;
|
||||||
|
|
||||||
|
public class SupabaseEventLogger : MonoBehaviour
|
||||||
|
{
|
||||||
|
public static SupabaseEventLogger Instance;
|
||||||
|
|
||||||
|
private DateTime sessionStartTime;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
if (Instance == null)
|
||||||
|
Instance = this;
|
||||||
|
else
|
||||||
|
Destroy(gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call this at the start of the game session.
|
||||||
|
/// </summary>
|
||||||
|
public async void StartSession()
|
||||||
|
{
|
||||||
|
sessionStartTime = DateTime.UtcNow;
|
||||||
|
|
||||||
|
var gameEvent = new GameEvent
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid(), // <== Ensure this is explicitly set
|
||||||
|
EventKey = "game_session_started",
|
||||||
|
Timestamp = sessionStartTime,
|
||||||
|
UserId = "user123"
|
||||||
|
};
|
||||||
|
await Client.Instance.From<GameEvent>().Insert(gameEvent);
|
||||||
|
Debug.Log("✅ Supabase Event: game_session_started");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Logs optimal/suboptimal decisions at runtime.
|
||||||
|
/// </summary>
|
||||||
|
public async void LogDecisionEvent(bool isOptimal)
|
||||||
|
{
|
||||||
|
string eventKey = isOptimal ? "game_optimal_decision_made" : "game_suboptimal_decision_made";
|
||||||
|
|
||||||
|
var gameEvent = new GameEvent
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid(),
|
||||||
|
EventKey = eventKey,
|
||||||
|
Timestamp = DateTime.UtcNow,
|
||||||
|
UserId = "user123"
|
||||||
|
};
|
||||||
|
|
||||||
|
await Client.Instance.From<GameEvent>().Insert(gameEvent);
|
||||||
|
Debug.Log($"✅ Supabase Event: {eventKey}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Completes the session and submits full results to phishing_game_attempts table.
|
||||||
|
/// </summary>
|
||||||
|
public async void CompleteSessionAndSubmitResult(string userId, bool passed, int optimal, int suboptimal, string scenarioId, List<Decision> decisionLog = null)
|
||||||
|
{
|
||||||
|
var endTime = DateTime.UtcNow;
|
||||||
|
int duration = (int)(endTime - sessionStartTime).TotalSeconds;
|
||||||
|
|
||||||
|
// Log completion events
|
||||||
|
await Client.Instance.From<GameEvent>().Insert(new GameEvent
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid(),
|
||||||
|
EventKey = "game_session_completed",
|
||||||
|
Timestamp = endTime,
|
||||||
|
UserId = userId
|
||||||
|
});
|
||||||
|
|
||||||
|
await Client.Instance.From<GameEvent>().Insert(new GameEvent
|
||||||
|
{Id = Guid.NewGuid(),
|
||||||
|
EventKey = "game_score_recorded",
|
||||||
|
Timestamp = endTime,
|
||||||
|
UserId = userId
|
||||||
|
});
|
||||||
|
|
||||||
|
// Insert session result
|
||||||
|
var gameAttempt = new GameAttempt
|
||||||
|
{
|
||||||
|
GameId = "phishing-awareness-1",
|
||||||
|
ScenarioId = scenarioId,
|
||||||
|
UserId = userId,
|
||||||
|
AttemptNumber = 1,
|
||||||
|
StartTime = sessionStartTime,
|
||||||
|
EndTime = endTime,
|
||||||
|
DurationSeconds = duration,
|
||||||
|
Score = passed ? 100 : 50,
|
||||||
|
Passed = passed,
|
||||||
|
Optimal = optimal,
|
||||||
|
Suboptimal = suboptimal,
|
||||||
|
KeyDecisionsLogJson = decisionLog != null ? JsonUtility.ToJson(new DecisionLogWrapper { decisions = decisionLog }) : "[]"
|
||||||
|
};
|
||||||
|
|
||||||
|
await Client.Instance.From<GameAttempt>().Insert(gameAttempt);
|
||||||
|
Debug.Log("✅ Supabase Game Result Submitted");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class Decision
|
||||||
|
{
|
||||||
|
public string decisionId;
|
||||||
|
public string timestamp;
|
||||||
|
public bool optimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class DecisionLogWrapper
|
||||||
|
{
|
||||||
|
public List<Decision> decisions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Existing SupabaseEventLogger class here...
|
||||||
|
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
|
||||||
|
|
||||||
|
[Table("game_events")]
|
||||||
|
public class GameEvent : BaseModel
|
||||||
|
{
|
||||||
|
[PrimaryKey("id", false)]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
[Column("event_key")]
|
||||||
|
public string EventKey { get; set; }
|
||||||
|
|
||||||
|
[Column("timestamp")]
|
||||||
|
public DateTime Timestamp { get; set; }
|
||||||
|
|
||||||
|
[Column("user_id")]
|
||||||
|
public string UserId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Table("phishing_game_attempts")]
|
||||||
|
public class GameAttempt : BaseModel
|
||||||
|
{
|
||||||
|
[PrimaryKey("id", false)]
|
||||||
|
public Guid Id { get; set; } = Guid.NewGuid();
|
||||||
|
|
||||||
|
[Column("game_id")]
|
||||||
|
public string GameId { get; set; }
|
||||||
|
|
||||||
|
[Column("scenario_id")]
|
||||||
|
public string ScenarioId { get; set; }
|
||||||
|
|
||||||
|
[Column("user_id")]
|
||||||
|
public string UserId { get; set; }
|
||||||
|
|
||||||
|
[Column("attempt_number")]
|
||||||
|
public int AttemptNumber { get; set; }
|
||||||
|
|
||||||
|
[Column("start_timestamp")]
|
||||||
|
public DateTime StartTime { get; set; }
|
||||||
|
|
||||||
|
[Column("end_timestamp")]
|
||||||
|
public DateTime EndTime { get; set; }
|
||||||
|
|
||||||
|
[Column("duration_seconds")]
|
||||||
|
public int DurationSeconds { get; set; }
|
||||||
|
|
||||||
|
[Column("final_score_percentage")]
|
||||||
|
public float Score { get; set; }
|
||||||
|
|
||||||
|
[Column("pass_fail_status")]
|
||||||
|
public bool Passed { get; set; }
|
||||||
|
|
||||||
|
[Column("optimal_decisions_count")]
|
||||||
|
public int Optimal { get; set; }
|
||||||
|
|
||||||
|
[Column("suboptimal_decisions_count")]
|
||||||
|
public int Suboptimal { get; set; }
|
||||||
|
|
||||||
|
[Column("key_decisions_log")]
|
||||||
|
public string KeyDecisionsLogJson { get; set; }
|
||||||
|
}
|
||||||
11
Assets/SupabaseEventLogger.cs.meta
Normal file
11
Assets/SupabaseEventLogger.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 50b27839ecef84443a10112beb860a7a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
31
Assets/SupabaseManager.cs
Normal file
31
Assets/SupabaseManager.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using Supabase;
|
||||||
|
using UnityEngine;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
public class SupabaseManager : MonoBehaviour
|
||||||
|
{
|
||||||
|
public static Supabase.Client Client => Supabase.Client.Instance;
|
||||||
|
|
||||||
|
[Header("Supabase Settings")]
|
||||||
|
public string supabaseUrl = "https://vihjspljbslozbjzxutl.supabase.co";
|
||||||
|
public string supabaseKey = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZpaGpzcGxqYnNsb3pianp4dXRsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDk1NDc4OTMsImV4cCI6MjA2NTEyMzg5M30.IYPvShgu5j3NnE5PHn-aFLCBJl1QQaVQvAjzxFt8tlA";
|
||||||
|
|
||||||
|
private async void Awake()
|
||||||
|
{
|
||||||
|
if (Supabase.Client.Instance != null)
|
||||||
|
{
|
||||||
|
Debug.Log("✅ Supabase already initialized.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = new SupabaseOptions
|
||||||
|
{
|
||||||
|
AutoConnectRealtime = false,
|
||||||
|
ShouldInitializeRealtime = false
|
||||||
|
};
|
||||||
|
|
||||||
|
await Supabase.Client.InitializeAsync(supabaseUrl, supabaseKey, options);
|
||||||
|
|
||||||
|
Debug.Log("✅ Supabase Initialized via static method");
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/SupabaseManager.cs.meta
Normal file
11
Assets/SupabaseManager.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ef01b27a4a6f3724a981d178a963c567
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
39
Assets/SupabaseTestInsert.cs
Normal file
39
Assets/SupabaseTestInsert.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using Supabase;
|
||||||
|
using System;
|
||||||
|
using Postgrest.Models;
|
||||||
|
using Postgrest.Attributes;
|
||||||
|
|
||||||
|
public class SupabaseTestInsert : MonoBehaviour
|
||||||
|
{
|
||||||
|
async void Start()
|
||||||
|
{
|
||||||
|
var gameEvent = new GameEvent
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid(),
|
||||||
|
EventKey = "manual_test_event",
|
||||||
|
Timestamp = DateTime.UtcNow,
|
||||||
|
UserId = "test_user_1"
|
||||||
|
};
|
||||||
|
|
||||||
|
Debug.Log("🔍 Trying test insert...");
|
||||||
|
await Client.Instance.From<GameEvent>().Insert(gameEvent);
|
||||||
|
Debug.Log("✅ Test insert complete");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Table("game_events")]
|
||||||
|
public class GameEvent : BaseModel
|
||||||
|
{
|
||||||
|
[PrimaryKey("id", false)]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
[Column("event_key")]
|
||||||
|
public string EventKey { get; set; }
|
||||||
|
|
||||||
|
[Column("timestamp")]
|
||||||
|
public DateTime Timestamp { get; set; }
|
||||||
|
|
||||||
|
[Column("user_id")]
|
||||||
|
public string UserId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/SupabaseTestInsert.cs.meta
Normal file
11
Assets/SupabaseTestInsert.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 619706b2e2fd4fe4eb36567a686c7da0
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Loading…
x
Reference in New Issue
Block a user