@playcademy/sdk 0.0.8 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import * as _playcademy_realtime_server_types from '@playcademy/realtime/server/types';
2
+ import { InferSelectModel } from 'drizzle-orm';
2
3
  import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
3
4
  import * as drizzle_zod from 'drizzle-zod';
4
5
  import { z } from 'zod';
6
+ import { OrganizationConfig, CourseConfig, ComponentConfig, ResourceConfig, ComponentResourceConfig } from '@playcademy/timeback/types';
5
7
 
6
8
  declare const users: drizzle_orm_pg_core.PgTableWithColumns<{
7
9
  name: "user";
@@ -1848,8 +1850,402 @@ declare const playerCharacterAccessories: drizzle_orm_pg_core.PgTableWithColumns
1848
1850
  };
1849
1851
  dialect: "pg";
1850
1852
  }>;
1853
+ declare const gameTimebackIntegrations: drizzle_orm_pg_core.PgTableWithColumns<{
1854
+ name: "game_timeback_integrations";
1855
+ schema: undefined;
1856
+ columns: {
1857
+ id: drizzle_orm_pg_core.PgColumn<{
1858
+ name: "id";
1859
+ tableName: "game_timeback_integrations";
1860
+ dataType: "string";
1861
+ columnType: "PgUUID";
1862
+ data: string;
1863
+ driverParam: string;
1864
+ notNull: true;
1865
+ hasDefault: true;
1866
+ isPrimaryKey: true;
1867
+ isAutoincrement: false;
1868
+ hasRuntimeDefault: false;
1869
+ enumValues: undefined;
1870
+ baseColumn: never;
1871
+ identity: undefined;
1872
+ generated: undefined;
1873
+ }, {}, {}>;
1874
+ gameId: drizzle_orm_pg_core.PgColumn<{
1875
+ name: "game_id";
1876
+ tableName: "game_timeback_integrations";
1877
+ dataType: "string";
1878
+ columnType: "PgUUID";
1879
+ data: string;
1880
+ driverParam: string;
1881
+ notNull: true;
1882
+ hasDefault: false;
1883
+ isPrimaryKey: false;
1884
+ isAutoincrement: false;
1885
+ hasRuntimeDefault: false;
1886
+ enumValues: undefined;
1887
+ baseColumn: never;
1888
+ identity: undefined;
1889
+ generated: undefined;
1890
+ }, {}, {}>;
1891
+ courseId: drizzle_orm_pg_core.PgColumn<{
1892
+ name: "course_id";
1893
+ tableName: "game_timeback_integrations";
1894
+ dataType: "string";
1895
+ columnType: "PgText";
1896
+ data: string;
1897
+ driverParam: string;
1898
+ notNull: true;
1899
+ hasDefault: false;
1900
+ isPrimaryKey: false;
1901
+ isAutoincrement: false;
1902
+ hasRuntimeDefault: false;
1903
+ enumValues: [string, ...string[]];
1904
+ baseColumn: never;
1905
+ identity: undefined;
1906
+ generated: undefined;
1907
+ }, {}, {}>;
1908
+ lastVerifiedAt: drizzle_orm_pg_core.PgColumn<{
1909
+ name: "last_verified_at";
1910
+ tableName: "game_timeback_integrations";
1911
+ dataType: "date";
1912
+ columnType: "PgTimestamp";
1913
+ data: Date;
1914
+ driverParam: string;
1915
+ notNull: false;
1916
+ hasDefault: false;
1917
+ isPrimaryKey: false;
1918
+ isAutoincrement: false;
1919
+ hasRuntimeDefault: false;
1920
+ enumValues: undefined;
1921
+ baseColumn: never;
1922
+ identity: undefined;
1923
+ generated: undefined;
1924
+ }, {}, {}>;
1925
+ createdAt: drizzle_orm_pg_core.PgColumn<{
1926
+ name: "created_at";
1927
+ tableName: "game_timeback_integrations";
1928
+ dataType: "date";
1929
+ columnType: "PgTimestamp";
1930
+ data: Date;
1931
+ driverParam: string;
1932
+ notNull: true;
1933
+ hasDefault: true;
1934
+ isPrimaryKey: false;
1935
+ isAutoincrement: false;
1936
+ hasRuntimeDefault: false;
1937
+ enumValues: undefined;
1938
+ baseColumn: never;
1939
+ identity: undefined;
1940
+ generated: undefined;
1941
+ }, {}, {}>;
1942
+ updatedAt: drizzle_orm_pg_core.PgColumn<{
1943
+ name: "updated_at";
1944
+ tableName: "game_timeback_integrations";
1945
+ dataType: "date";
1946
+ columnType: "PgTimestamp";
1947
+ data: Date;
1948
+ driverParam: string;
1949
+ notNull: true;
1950
+ hasDefault: true;
1951
+ isPrimaryKey: false;
1952
+ isAutoincrement: false;
1953
+ hasRuntimeDefault: false;
1954
+ enumValues: undefined;
1955
+ baseColumn: never;
1956
+ identity: undefined;
1957
+ generated: undefined;
1958
+ }, {}, {}>;
1959
+ };
1960
+ dialect: "pg";
1961
+ }>;
1851
1962
 
1852
- declare const achievementIntervalEnum: drizzle_orm_pg_core.PgEnum<["daily", "weekly"]>;
1963
+ declare const achievementScopeEnum: drizzle_orm_pg_core.PgEnum<["daily", "weekly", "monthly", "yearly", "game", "global", "map", "level", "event"]>;
1964
+ declare const notifications: drizzle_orm_pg_core.PgTableWithColumns<{
1965
+ name: "notifications";
1966
+ schema: undefined;
1967
+ columns: {
1968
+ id: drizzle_orm_pg_core.PgColumn<{
1969
+ name: "id";
1970
+ tableName: "notifications";
1971
+ dataType: "string";
1972
+ columnType: "PgUUID";
1973
+ data: string;
1974
+ driverParam: string;
1975
+ notNull: true;
1976
+ hasDefault: true;
1977
+ isPrimaryKey: true;
1978
+ isAutoincrement: false;
1979
+ hasRuntimeDefault: false;
1980
+ enumValues: undefined;
1981
+ baseColumn: never;
1982
+ identity: undefined;
1983
+ generated: undefined;
1984
+ }, {}, {}>;
1985
+ userId: drizzle_orm_pg_core.PgColumn<{
1986
+ name: "user_id";
1987
+ tableName: "notifications";
1988
+ dataType: "string";
1989
+ columnType: "PgText";
1990
+ data: string;
1991
+ driverParam: string;
1992
+ notNull: true;
1993
+ hasDefault: false;
1994
+ isPrimaryKey: false;
1995
+ isAutoincrement: false;
1996
+ hasRuntimeDefault: false;
1997
+ enumValues: [string, ...string[]];
1998
+ baseColumn: never;
1999
+ identity: undefined;
2000
+ generated: undefined;
2001
+ }, {}, {}>;
2002
+ type: drizzle_orm_pg_core.PgColumn<{
2003
+ name: "type";
2004
+ tableName: "notifications";
2005
+ dataType: "string";
2006
+ columnType: "PgVarchar";
2007
+ data: string;
2008
+ driverParam: string;
2009
+ notNull: true;
2010
+ hasDefault: false;
2011
+ isPrimaryKey: false;
2012
+ isAutoincrement: false;
2013
+ hasRuntimeDefault: false;
2014
+ enumValues: [string, ...string[]];
2015
+ baseColumn: never;
2016
+ identity: undefined;
2017
+ generated: undefined;
2018
+ }, {}, {
2019
+ length: 50;
2020
+ }>;
2021
+ title: drizzle_orm_pg_core.PgColumn<{
2022
+ name: "title";
2023
+ tableName: "notifications";
2024
+ dataType: "string";
2025
+ columnType: "PgVarchar";
2026
+ data: string;
2027
+ driverParam: string;
2028
+ notNull: true;
2029
+ hasDefault: false;
2030
+ isPrimaryKey: false;
2031
+ isAutoincrement: false;
2032
+ hasRuntimeDefault: false;
2033
+ enumValues: [string, ...string[]];
2034
+ baseColumn: never;
2035
+ identity: undefined;
2036
+ generated: undefined;
2037
+ }, {}, {
2038
+ length: 255;
2039
+ }>;
2040
+ message: drizzle_orm_pg_core.PgColumn<{
2041
+ name: "message";
2042
+ tableName: "notifications";
2043
+ dataType: "string";
2044
+ columnType: "PgText";
2045
+ data: string;
2046
+ driverParam: string;
2047
+ notNull: true;
2048
+ hasDefault: false;
2049
+ isPrimaryKey: false;
2050
+ isAutoincrement: false;
2051
+ hasRuntimeDefault: false;
2052
+ enumValues: [string, ...string[]];
2053
+ baseColumn: never;
2054
+ identity: undefined;
2055
+ generated: undefined;
2056
+ }, {}, {}>;
2057
+ data: drizzle_orm_pg_core.PgColumn<{
2058
+ name: "data";
2059
+ tableName: "notifications";
2060
+ dataType: "json";
2061
+ columnType: "PgJsonb";
2062
+ data: unknown;
2063
+ driverParam: unknown;
2064
+ notNull: true;
2065
+ hasDefault: true;
2066
+ isPrimaryKey: false;
2067
+ isAutoincrement: false;
2068
+ hasRuntimeDefault: false;
2069
+ enumValues: undefined;
2070
+ baseColumn: never;
2071
+ identity: undefined;
2072
+ generated: undefined;
2073
+ }, {}, {}>;
2074
+ priority: drizzle_orm_pg_core.PgColumn<{
2075
+ name: "priority";
2076
+ tableName: "notifications";
2077
+ dataType: "string";
2078
+ columnType: "PgEnumColumn";
2079
+ data: "low" | "normal" | "high" | "urgent";
2080
+ driverParam: string;
2081
+ notNull: true;
2082
+ hasDefault: true;
2083
+ isPrimaryKey: false;
2084
+ isAutoincrement: false;
2085
+ hasRuntimeDefault: false;
2086
+ enumValues: ["low", "normal", "high", "urgent"];
2087
+ baseColumn: never;
2088
+ identity: undefined;
2089
+ generated: undefined;
2090
+ }, {}, {}>;
2091
+ status: drizzle_orm_pg_core.PgColumn<{
2092
+ name: "status";
2093
+ tableName: "notifications";
2094
+ dataType: "string";
2095
+ columnType: "PgEnumColumn";
2096
+ data: "pending" | "delivered" | "seen" | "clicked" | "dismissed" | "expired";
2097
+ driverParam: string;
2098
+ notNull: true;
2099
+ hasDefault: true;
2100
+ isPrimaryKey: false;
2101
+ isAutoincrement: false;
2102
+ hasRuntimeDefault: false;
2103
+ enumValues: ["pending", "delivered", "seen", "clicked", "dismissed", "expired"];
2104
+ baseColumn: never;
2105
+ identity: undefined;
2106
+ generated: undefined;
2107
+ }, {}, {}>;
2108
+ createdAt: drizzle_orm_pg_core.PgColumn<{
2109
+ name: "created_at";
2110
+ tableName: "notifications";
2111
+ dataType: "date";
2112
+ columnType: "PgTimestamp";
2113
+ data: Date;
2114
+ driverParam: string;
2115
+ notNull: true;
2116
+ hasDefault: true;
2117
+ isPrimaryKey: false;
2118
+ isAutoincrement: false;
2119
+ hasRuntimeDefault: false;
2120
+ enumValues: undefined;
2121
+ baseColumn: never;
2122
+ identity: undefined;
2123
+ generated: undefined;
2124
+ }, {}, {}>;
2125
+ deliveredAt: drizzle_orm_pg_core.PgColumn<{
2126
+ name: "delivered_at";
2127
+ tableName: "notifications";
2128
+ dataType: "date";
2129
+ columnType: "PgTimestamp";
2130
+ data: Date;
2131
+ driverParam: string;
2132
+ notNull: false;
2133
+ hasDefault: false;
2134
+ isPrimaryKey: false;
2135
+ isAutoincrement: false;
2136
+ hasRuntimeDefault: false;
2137
+ enumValues: undefined;
2138
+ baseColumn: never;
2139
+ identity: undefined;
2140
+ generated: undefined;
2141
+ }, {}, {}>;
2142
+ seenAt: drizzle_orm_pg_core.PgColumn<{
2143
+ name: "seen_at";
2144
+ tableName: "notifications";
2145
+ dataType: "date";
2146
+ columnType: "PgTimestamp";
2147
+ data: Date;
2148
+ driverParam: string;
2149
+ notNull: false;
2150
+ hasDefault: false;
2151
+ isPrimaryKey: false;
2152
+ isAutoincrement: false;
2153
+ hasRuntimeDefault: false;
2154
+ enumValues: undefined;
2155
+ baseColumn: never;
2156
+ identity: undefined;
2157
+ generated: undefined;
2158
+ }, {}, {}>;
2159
+ clickedAt: drizzle_orm_pg_core.PgColumn<{
2160
+ name: "clicked_at";
2161
+ tableName: "notifications";
2162
+ dataType: "date";
2163
+ columnType: "PgTimestamp";
2164
+ data: Date;
2165
+ driverParam: string;
2166
+ notNull: false;
2167
+ hasDefault: false;
2168
+ isPrimaryKey: false;
2169
+ isAutoincrement: false;
2170
+ hasRuntimeDefault: false;
2171
+ enumValues: undefined;
2172
+ baseColumn: never;
2173
+ identity: undefined;
2174
+ generated: undefined;
2175
+ }, {}, {}>;
2176
+ expiresAt: drizzle_orm_pg_core.PgColumn<{
2177
+ name: "expires_at";
2178
+ tableName: "notifications";
2179
+ dataType: "date";
2180
+ columnType: "PgTimestamp";
2181
+ data: Date;
2182
+ driverParam: string;
2183
+ notNull: false;
2184
+ hasDefault: false;
2185
+ isPrimaryKey: false;
2186
+ isAutoincrement: false;
2187
+ hasRuntimeDefault: false;
2188
+ enumValues: undefined;
2189
+ baseColumn: never;
2190
+ identity: undefined;
2191
+ generated: undefined;
2192
+ }, {}, {}>;
2193
+ method: drizzle_orm_pg_core.PgColumn<{
2194
+ name: "method";
2195
+ tableName: "notifications";
2196
+ dataType: "string";
2197
+ columnType: "PgVarchar";
2198
+ data: string;
2199
+ driverParam: string;
2200
+ notNull: false;
2201
+ hasDefault: false;
2202
+ isPrimaryKey: false;
2203
+ isAutoincrement: false;
2204
+ hasRuntimeDefault: false;
2205
+ enumValues: [string, ...string[]];
2206
+ baseColumn: never;
2207
+ identity: undefined;
2208
+ generated: undefined;
2209
+ }, {}, {
2210
+ length: 50;
2211
+ }>;
2212
+ clickUrl: drizzle_orm_pg_core.PgColumn<{
2213
+ name: "click_url";
2214
+ tableName: "notifications";
2215
+ dataType: "string";
2216
+ columnType: "PgText";
2217
+ data: string;
2218
+ driverParam: string;
2219
+ notNull: false;
2220
+ hasDefault: false;
2221
+ isPrimaryKey: false;
2222
+ isAutoincrement: false;
2223
+ hasRuntimeDefault: false;
2224
+ enumValues: [string, ...string[]];
2225
+ baseColumn: never;
2226
+ identity: undefined;
2227
+ generated: undefined;
2228
+ }, {}, {}>;
2229
+ metadata: drizzle_orm_pg_core.PgColumn<{
2230
+ name: "metadata";
2231
+ tableName: "notifications";
2232
+ dataType: "json";
2233
+ columnType: "PgJsonb";
2234
+ data: unknown;
2235
+ driverParam: unknown;
2236
+ notNull: true;
2237
+ hasDefault: true;
2238
+ isPrimaryKey: false;
2239
+ isAutoincrement: false;
2240
+ hasRuntimeDefault: false;
2241
+ enumValues: undefined;
2242
+ baseColumn: never;
2243
+ identity: undefined;
2244
+ generated: undefined;
2245
+ }, {}, {}>;
2246
+ };
2247
+ dialect: "pg";
2248
+ }>;
1853
2249
  declare const DeveloperStatusResponseSchema: z.ZodObject<{
1854
2250
  status: z.ZodEnum<["none", "pending", "approved"]>;
1855
2251
  }, "strip", z.ZodTypeAny, {
@@ -2247,11 +2643,82 @@ declare const UpdateShopListingSchema: z.ZodObject<{
2247
2643
  availableFrom?: Date | null | undefined;
2248
2644
  availableUntil?: Date | null | undefined;
2249
2645
  }>;
2646
+
2647
+ declare enum AchievementCompletionType {
2648
+ TIME_PLAYED_SESSION = "time_played_session",
2649
+ INTERACTION = "interaction",
2650
+ LEADERBOARD_RANK = "leaderboard_rank",
2651
+ FIRST_SCORE = "first_score",
2652
+ PERSONAL_BEST = "personal_best"
2653
+ }
2654
+ type AchievementScopeType = (typeof achievementScopeEnum.enumValues)[number];
2250
2655
  /**
2251
- * Achievement Completion Types
2656
+ * Current-scope achievement with computed status and window metadata
2252
2657
  */
2253
- declare const ACHIEVEMENT_COMPLETION_TYPES: readonly ["time_played_session", "interaction", "leaderboard_rank"];
2254
- type AchievementCompletionType = (typeof ACHIEVEMENT_COMPLETION_TYPES)[number];
2658
+ interface AchievementCurrent {
2659
+ id: string;
2660
+ title: string;
2661
+ description?: string | null;
2662
+ scope: AchievementScopeType;
2663
+ rewardCredits: number;
2664
+ limit: number;
2665
+ completionType: AchievementCompletionType;
2666
+ completionConfig: Record<string, unknown>;
2667
+ target: Record<string, unknown>;
2668
+ active: boolean;
2669
+ createdAt?: Date;
2670
+ updatedAt?: Date;
2671
+ status: 'available' | 'completed';
2672
+ scopeKey: string;
2673
+ windowStart: string;
2674
+ windowEnd: string;
2675
+ }
2676
+ /**
2677
+ * Achievement claim history entry
2678
+ * Used in GET /api/achievements/history
2679
+ */
2680
+ interface AchievementHistoryEntry {
2681
+ achievementId: string;
2682
+ title: string;
2683
+ rewardCredits: number;
2684
+ createdAt: string;
2685
+ scopeKey: string;
2686
+ }
2687
+ /**
2688
+ * Achievement progress submission response
2689
+ * Used in POST /api/achievements/progress
2690
+ */
2691
+ interface AchievementProgressResponse {
2692
+ achievementId: string;
2693
+ status: 'completed' | 'already_completed';
2694
+ rewardCredits: number;
2695
+ scopeKey: string;
2696
+ createdAt: string;
2697
+ }
2698
+
2699
+ declare enum NotificationType {
2700
+ ACHIEVEMENT = "achievement",
2701
+ SYSTEM = "system",
2702
+ PROMO = "promo"
2703
+ }
2704
+ declare enum NotificationStatus {
2705
+ PENDING = "pending",
2706
+ DELIVERED = "delivered",
2707
+ SEEN = "seen",
2708
+ CLICKED = "clicked",
2709
+ DISMISSED = "dismissed",
2710
+ EXPIRED = "expired"
2711
+ }
2712
+ type Notification = InferSelectModel<typeof notifications>;
2713
+ interface NotificationStats {
2714
+ total: number;
2715
+ delivered: number;
2716
+ seen: number;
2717
+ clicked: number;
2718
+ dismissed: number;
2719
+ expired: number;
2720
+ clickThroughRate: number;
2721
+ }
2255
2722
 
2256
2723
  type CharacterComponent = typeof characterComponents.$inferSelect;
2257
2724
  type PlayerCharacter = typeof playerCharacters.$inferSelect & {
@@ -2273,6 +2740,17 @@ type ExternalGame = BaseGame & {
2273
2740
  type Game = HostedGame | ExternalGame;
2274
2741
  type GameStateData = Record<string, unknown>;
2275
2742
  type UpsertGameMetadataInput = z.infer<typeof UpsertGameMetadataSchema>;
2743
+ /**
2744
+ * Response from backend deployment API
2745
+ */
2746
+ interface BackendDeploymentResponse {
2747
+ /** Unique deployment ID */
2748
+ deploymentId: string;
2749
+ /** Backend API URL */
2750
+ url: string;
2751
+ /** Deployment timestamp */
2752
+ deployedAt: string;
2753
+ }
2276
2754
  type Item = typeof items.$inferSelect;
2277
2755
  type InventoryItem = typeof inventoryItems.$inferSelect;
2278
2756
  type ShopListing = typeof shopListings.$inferSelect;
@@ -2341,6 +2819,8 @@ interface UserInfo {
2341
2819
  given_name?: string;
2342
2820
  /** Optional family name (last name) */
2343
2821
  family_name?: string;
2822
+ /** TimeBack student ID (if user has TimeBack integration) */
2823
+ timeback_id?: string;
2344
2824
  /** Additional user attributes from the identity provider */
2345
2825
  [key: string]: unknown;
2346
2826
  }
@@ -2527,6 +3007,7 @@ interface SpriteTemplateData {
2527
3007
  };
2528
3008
  };
2529
3009
  }
3010
+ type GameTimebackIntegration = typeof gameTimebackIntegrations.$inferSelect;
2530
3011
  type TodayXpResponse = {
2531
3012
  xp: number;
2532
3013
  date: string;
@@ -2540,49 +3021,157 @@ type XpHistoryResponse = {
2540
3021
  xp: number;
2541
3022
  }>;
2542
3023
  };
2543
-
2544
- type AchievementIntervalType = (typeof achievementIntervalEnum.enumValues)[number];
2545
- /**
2546
- * Current-interval achievement with computed status and window metadata
2547
- */
2548
- interface AchievementCurrent {
2549
- id: string;
2550
- title: string;
2551
- description?: string | null;
2552
- intervalType: AchievementIntervalType;
2553
- rewardCredits: number;
2554
- limitPerInterval: number;
2555
- completionType: AchievementCompletionType;
2556
- completionConfig: Record<string, unknown>;
2557
- scope: Record<string, unknown>;
2558
- active: boolean;
2559
- createdAt?: Date;
2560
- updatedAt?: Date;
2561
- status: 'available' | 'completed';
2562
- intervalKey: string;
2563
- windowStart: string;
2564
- windowEnd: string;
2565
- }
2566
- /**
2567
- * Historical entry representing a prior claim within an interval
2568
- */
2569
- interface AchievementHistoryEntry {
2570
- achievementId: string;
2571
- title: string;
2572
- rewardCredits: number;
2573
- createdAt: string;
2574
- intervalKey: string;
2575
- }
2576
- /**
2577
- * Response returned when submitting achievement progress
2578
- */
2579
- interface AchievementProgressResponse {
2580
- achievementId: string;
2581
- status: 'completed' | 'already_completed';
2582
- rewardCredits: number;
2583
- intervalKey: string;
2584
- createdAt: string;
2585
- }
3024
+ type TimebackSetupRequest = {
3025
+ gameId: string;
3026
+ config: {
3027
+ organization: {
3028
+ name: string;
3029
+ type: string;
3030
+ identifier: string;
3031
+ };
3032
+ course: {
3033
+ title: string;
3034
+ subjects: string[];
3035
+ grades: number[];
3036
+ courseCode: string;
3037
+ level: string;
3038
+ gradingScheme: string;
3039
+ metadata?: Record<string, unknown>;
3040
+ };
3041
+ component: {
3042
+ title: string;
3043
+ sortOrder: number;
3044
+ prerequisites: string[];
3045
+ prerequisiteCriteria: string;
3046
+ };
3047
+ resource: {
3048
+ title: string;
3049
+ vendorResourceId: string;
3050
+ vendorId: string;
3051
+ applicationId: string;
3052
+ roles: string[];
3053
+ importance: string;
3054
+ metadata: {
3055
+ type?: string;
3056
+ launchUrl?: string;
3057
+ toolProvider?: string;
3058
+ instructionalMethod?: string;
3059
+ subject?: string;
3060
+ grades?: number[];
3061
+ language?: string;
3062
+ xp?: number;
3063
+ [key: string]: unknown;
3064
+ };
3065
+ };
3066
+ componentResource: {
3067
+ title: string;
3068
+ sortOrder: number;
3069
+ lessonType: string | null;
3070
+ };
3071
+ };
3072
+ verbose?: boolean;
3073
+ };
3074
+ type TimebackSetupResponse = {
3075
+ integration: GameTimebackIntegration;
3076
+ courseId: string;
3077
+ verbose?: {
3078
+ course: unknown;
3079
+ component: unknown;
3080
+ resource: unknown;
3081
+ componentResource: unknown;
3082
+ };
3083
+ };
3084
+ type TimebackVerifyResponse = {
3085
+ status: 'success' | 'error';
3086
+ integration: GameTimebackIntegration;
3087
+ resources: {
3088
+ course: {
3089
+ found: boolean;
3090
+ data?: unknown;
3091
+ };
3092
+ component: {
3093
+ found: boolean;
3094
+ data?: unknown;
3095
+ };
3096
+ resource: {
3097
+ found: boolean;
3098
+ data?: unknown;
3099
+ };
3100
+ componentResource: {
3101
+ found: boolean;
3102
+ data?: unknown;
3103
+ };
3104
+ };
3105
+ errors?: string[];
3106
+ };
3107
+ type RecordProgressRequest = {
3108
+ gameId: string;
3109
+ studentId: string;
3110
+ progressData: {
3111
+ score?: number;
3112
+ totalQuestions?: number;
3113
+ correctQuestions?: number;
3114
+ xpEarned?: number;
3115
+ masteredUnits?: number;
3116
+ attemptNumber?: number;
3117
+ activityId?: string;
3118
+ activityName?: string;
3119
+ courseId?: string;
3120
+ classId?: string;
3121
+ courseName?: string;
3122
+ studentEmail?: string;
3123
+ subject?: 'Reading' | 'Language' | 'Vocabulary' | 'Social Studies' | 'Writing' | 'Science' | 'FastMath' | 'Math' | 'None';
3124
+ appName?: string;
3125
+ sensorUrl?: string;
3126
+ };
3127
+ };
3128
+ type RecordProgressResponse = {
3129
+ status: 'ok';
3130
+ courseId: string;
3131
+ };
3132
+ type RecordSessionEndRequest = {
3133
+ gameId: string;
3134
+ studentId: string;
3135
+ sessionData: {
3136
+ activeTimeSeconds: number;
3137
+ inactiveTimeSeconds?: number;
3138
+ wasteTimeSeconds?: number;
3139
+ activityId?: string;
3140
+ activityName?: string;
3141
+ courseId?: string;
3142
+ courseName?: string;
3143
+ studentEmail?: string;
3144
+ subject?: 'Reading' | 'Language' | 'Vocabulary' | 'Social Studies' | 'Writing' | 'Science' | 'FastMath' | 'Math' | 'None';
3145
+ appName?: string;
3146
+ sensorUrl?: string;
3147
+ };
3148
+ };
3149
+ type RecordSessionEndResponse = {
3150
+ status: 'ok';
3151
+ courseId: string;
3152
+ };
3153
+ type AwardXpRequest = {
3154
+ gameId: string;
3155
+ studentId: string;
3156
+ xpAmount: number;
3157
+ metadata: {
3158
+ reason: string;
3159
+ activityId?: string;
3160
+ activityName?: string;
3161
+ courseId?: string;
3162
+ courseName?: string;
3163
+ studentEmail?: string;
3164
+ bonusType?: string;
3165
+ subject?: 'Reading' | 'Language' | 'Vocabulary' | 'Social Studies' | 'Writing' | 'Science' | 'FastMath' | 'Math' | 'None';
3166
+ appName?: string;
3167
+ sensorUrl?: string;
3168
+ };
3169
+ };
3170
+ type AwardXpResponse = {
3171
+ status: 'ok';
3172
+ courseId: string;
3173
+ xpAwarded: number;
3174
+ };
2586
3175
 
2587
3176
  /**
2588
3177
  * SDK Constants
@@ -2602,9 +3191,80 @@ declare const AuthProvider: {
2602
3191
  readonly TIMEBACK: "TIMEBACK";
2603
3192
  };
2604
3193
 
3194
+ /**
3195
+ * @fileoverview Server SDK Type Definitions
3196
+ *
3197
+ * TypeScript type definitions for the server-side Playcademy SDK.
3198
+ * Includes configuration types, client state, and re-exported TimeBack types.
3199
+ */
3200
+
3201
+ /**
3202
+ * TimeBack integration configuration for Playcademy config file
3203
+ */
3204
+ interface TimebackIntegrationConfig {
3205
+ /** Organization overrides */
3206
+ organization?: Partial<OrganizationConfig>;
3207
+ /** Course configuration (subjects and grades REQUIRED) */
3208
+ course: CourseConfig;
3209
+ /** Component overrides */
3210
+ component?: Partial<ComponentConfig>;
3211
+ /** Resource overrides */
3212
+ resource?: Partial<ResourceConfig>;
3213
+ /** Component-Resource link overrides */
3214
+ componentResource?: Partial<ComponentResourceConfig>;
3215
+ }
3216
+ /**
3217
+ * Integrations configuration
3218
+ */
3219
+ interface IntegrationsConfig {
3220
+ /** TimeBack integration (optional) */
3221
+ timeback?: TimebackIntegrationConfig;
3222
+ }
3223
+ /**
3224
+ * Unified Playcademy configuration
3225
+ * Used for playcademy.config.{js,json}
3226
+ */
3227
+ interface PlaycademyConfig {
3228
+ /** Game name */
3229
+ name: string;
3230
+ /** Game description */
3231
+ description?: string;
3232
+ /** Game emoji icon */
3233
+ emoji?: string;
3234
+ /** Build command to run before deployment */
3235
+ buildCommand?: string[];
3236
+ /** Path to build output */
3237
+ buildPath?: string;
3238
+ /** Game type */
3239
+ gameType?: 'hosted' | 'external';
3240
+ /** External URL (for external games) */
3241
+ externalUrl?: string;
3242
+ /** Game platform */
3243
+ platform?: 'web' | 'unity' | 'godot';
3244
+ /** Backend configuration */
3245
+ backend?: {
3246
+ /** Custom API routes directory (defaults to 'api') */
3247
+ directory?: string;
3248
+ };
3249
+ /** External integrations */
3250
+ integrations?: IntegrationsConfig;
3251
+ }
3252
+
3253
+ /**
3254
+ * Backend deployment bundle for uploading to Playcademy platform
3255
+ */
3256
+ interface BackendDeploymentBundle {
3257
+ /** Bundled JavaScript code ready for deployment */
3258
+ code: string;
3259
+ /** Game configuration */
3260
+ config: PlaycademyConfig;
3261
+ }
3262
+
3263
+ type TokenType = 'session' | 'apiKey' | 'gameJwt';
2605
3264
  interface ClientConfig {
2606
3265
  baseUrl: string;
2607
3266
  token?: string;
3267
+ tokenType?: TokenType;
2608
3268
  gameId?: string;
2609
3269
  autoStartSession?: boolean;
2610
3270
  }
@@ -2767,6 +3427,32 @@ type DevUploadHooks = {
2767
3427
  onEvent?: (e: DevUploadEvent) => void;
2768
3428
  onClose?: () => void;
2769
3429
  };
3430
+ /**
3431
+ * Better-auth API key creation response
3432
+ */
3433
+ interface BetterAuthApiKeyResponse {
3434
+ apiKey: string;
3435
+ key: {
3436
+ id: string;
3437
+ name: string | null;
3438
+ expiresAt: string | null;
3439
+ createdAt: string;
3440
+ };
3441
+ }
3442
+ /**
3443
+ * Better-auth API key list item
3444
+ */
3445
+ interface BetterAuthApiKey {
3446
+ id: string;
3447
+ name: string | null;
3448
+ start: string;
3449
+ enabled: boolean;
3450
+ expiresAt: string | null;
3451
+ createdAt: string;
3452
+ updatedAt: string;
3453
+ lastRequest: string | null;
3454
+ requestCount: number;
3455
+ }
2770
3456
 
2771
3457
  /**
2772
3458
  * OAuth 2.0 implementation for the Playcademy SDK
@@ -2935,7 +3621,7 @@ type Method = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
2935
3621
  */
2936
3622
  declare class PlaycademyClient {
2937
3623
  private baseUrl;
2938
- private token?;
3624
+ private authStrategy;
2939
3625
  private gameId?;
2940
3626
  private config;
2941
3627
  private listeners;
@@ -2948,6 +3634,7 @@ declare class PlaycademyClient {
2948
3634
  * @param config - Optional configuration object
2949
3635
  * @param config.baseUrl - Base URL for API requests (defaults to '/api')
2950
3636
  * @param config.token - Authentication token
3637
+ * @param config.tokenType - Optional token type (auto-detected if not provided)
2951
3638
  * @param config.gameId - Game ID for automatic session management
2952
3639
  * @param config.autoStartSession - Automatically start a game session?
2953
3640
  */
@@ -2970,8 +3657,15 @@ declare class PlaycademyClient {
2970
3657
  * Emits an 'authChange' event when the token changes.
2971
3658
  *
2972
3659
  * @param token - The authentication token, or null to clear
3660
+ * @param tokenType - Optional token type (auto-detected if not provided)
2973
3661
  */
2974
- setToken(token: string | null): void;
3662
+ setToken(token: string | null, tokenType?: TokenType): void;
3663
+ /**
3664
+ * Gets the current token type.
3665
+ *
3666
+ * @returns The token type
3667
+ */
3668
+ getTokenType(): TokenType;
2975
3669
  /**
2976
3670
  * Gets the current authentication token.
2977
3671
  *
@@ -3076,9 +3770,23 @@ declare class PlaycademyClient {
3076
3770
  }) => Promise<{
3077
3771
  success: boolean;
3078
3772
  token?: string;
3773
+ user?: {
3774
+ id: string;
3775
+ email: string;
3776
+ };
3777
+ expiresAt?: string;
3079
3778
  error?: string;
3080
3779
  }>;
3081
3780
  logout: () => Promise<void>;
3781
+ apiKeys: {
3782
+ create: (options?: {
3783
+ name?: string;
3784
+ expiresIn?: number | null;
3785
+ permissions?: Record<string, string[]>;
3786
+ }) => Promise<BetterAuthApiKeyResponse>;
3787
+ list: () => Promise<BetterAuthApiKey[]>;
3788
+ revoke: (keyId: string) => Promise<void>;
3789
+ };
3082
3790
  };
3083
3791
  /** Identity provider connection methods (connect external accounts) */
3084
3792
  identity: {
@@ -3129,7 +3837,7 @@ declare class PlaycademyClient {
3129
3837
  };
3130
3838
  leaderboard: {
3131
3839
  get: (gameId: string, options?: {
3132
- limit? /** Runtime methods (getGameToken, exit) */: number;
3840
+ limit?: number;
3133
3841
  offset?: number;
3134
3842
  }) => Promise<LeaderboardEntry[]>;
3135
3843
  };
@@ -3161,27 +3869,13 @@ declare class PlaycademyClient {
3161
3869
  get: () => Promise<DeveloperStatusValue>;
3162
3870
  };
3163
3871
  games: {
3164
- upsert: (slug: string, metadata: UpsertGameMetadataInput, file: File | Blob | null, hooks?: DevUploadHooks) => Promise<Game>;
3165
- update: (gameId: string, props: Partial<Game>) => Promise<void>;
3872
+ deploy: {
3873
+ frontend: (slug: string, metadata: UpsertGameMetadataInput, file: File | Blob | null, hooks?: DevUploadHooks) => Promise<Game>;
3874
+ backend: (slug: string, bundle: BackendDeploymentBundle) => Promise<BackendDeploymentResponse>;
3875
+ };
3876
+ upsert: (slug: string, metadata: UpsertGameMetadataInput) => Promise<Game>;
3166
3877
  delete: (gameId: string) => Promise<void>;
3167
3878
  };
3168
- keys: {
3169
- create: (label?: string) => Promise<{
3170
- id: string;
3171
- createdAt: Date;
3172
- userId: string;
3173
- label: string | null;
3174
- keyHash: string;
3175
- }>;
3176
- list: () => Promise<{
3177
- id: string;
3178
- createdAt: Date;
3179
- userId: string;
3180
- label: string | null;
3181
- keyHash: string;
3182
- }[]>;
3183
- revoke: (keyId: string) => Promise<void>;
3184
- };
3185
3879
  items: {
3186
3880
  create: (gameId: string, slug: string, itemData: Omit<InsertItemInput, "slug" | "gameId">) => Promise<Item>;
3187
3881
  update: (gameId: string, itemId: string, updates: UpdateItemInput) => Promise<Item>;
@@ -3201,8 +3895,8 @@ declare class PlaycademyClient {
3201
3895
  };
3202
3896
  /** Map methods (elements) */
3203
3897
  maps: {
3204
- get: (identifier: string) => Promise<MapData>;
3205
- elements: (mapId: string) => Promise<MapElementWithGame[]>;
3898
+ get: (identifier: string, options?: TTLCacheConfig) => Promise<MapData>;
3899
+ elements: (mapId: string, options?: TTLCacheConfig) => Promise<MapElementWithGame[]>;
3206
3900
  objects: {
3207
3901
  list: (mapId: string) => Promise<MapObjectWithItem[]>;
3208
3902
  create: (mapId: string, objectData: CreateMapObjectData) => Promise<MapObjectWithItem>;
@@ -3377,6 +4071,16 @@ declare class PlaycademyClient {
3377
4071
  };
3378
4072
  /** TimeBack XP methods (today, total, history) */
3379
4073
  timeback: {
4074
+ recordProgress: (progressData: RecordProgressRequest["progressData"]) => Promise<RecordProgressResponse>;
4075
+ recordSessionEnd: (sessionData: RecordSessionEndRequest["sessionData"]) => Promise<RecordSessionEndResponse>;
4076
+ awardXP: (xpAmount: number, metadata: AwardXpRequest["metadata"]) => Promise<AwardXpResponse>;
4077
+ management: {
4078
+ setup: (request: TimebackSetupRequest) => Promise<TimebackSetupResponse>;
4079
+ verify: (gameId: string) => Promise<TimebackVerifyResponse>;
4080
+ cleanup: (gameId: string) => Promise<void>;
4081
+ get: (gameId: string) => Promise<GameTimebackIntegration | null>;
4082
+ getConfig: (gameId: string) => Promise<TimebackSetupRequest["config"]>;
4083
+ };
3380
4084
  xp: {
3381
4085
  today: (options?: {
3382
4086
  date?: string;
@@ -3384,7 +4088,7 @@ declare class PlaycademyClient {
3384
4088
  }) => Promise<TodayXpResponse>;
3385
4089
  total: () => Promise<TotalXpResponse>;
3386
4090
  history: (options?: {
3387
- startDate?: string;
4091
+ startDate? /** TimeBack XP methods (today, total, history) */: string;
3388
4092
  endDate?: string;
3389
4093
  }) => Promise<XpHistoryResponse>;
3390
4094
  summary: (options?: {
@@ -3458,6 +4162,24 @@ declare class PlaycademyClient {
3458
4162
  submit: (achievementId: string) => Promise<AchievementProgressResponse>;
3459
4163
  };
3460
4164
  };
4165
+ /** Notifications methods (list, update status, stats) */
4166
+ notifications: {
4167
+ list: (queryOptions?: {
4168
+ status?: NotificationStatus;
4169
+ type?: NotificationType;
4170
+ limit?: number;
4171
+ offset?: number;
4172
+ }, cacheOptions?: TTLCacheConfig) => Promise<Notification[]>;
4173
+ markAsSeen: (notificationId: string) => Promise<Notification>;
4174
+ markAsClicked: (notificationId: string) => Promise<Notification>;
4175
+ dismiss: (notificationId: string) => Promise<Notification>;
4176
+ stats: {
4177
+ get: (queryOptions?: {
4178
+ from?: string;
4179
+ to?: string;
4180
+ }, cacheOptions?: TTLCacheConfig) => Promise<NotificationStats>;
4181
+ };
4182
+ };
3461
4183
  /** Auto-initializes a PlaycademyClient with context from the environment */
3462
4184
  static init: typeof init;
3463
4185
  /** Authenticates a user with email and password */